mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
Currency package update (#247)
* Initial currency overhaul before service system implementation * Remove redundant currency string in orderbook.Base Unexport lastupdated field in orderbook.Base as it was being instantiated multiple times Add error handling for process orderbook * Remove redundant currency string in ticker.Price Unexport lastupdated field in ticker.Price Add error handling for process ticker function and fix tests * Phase Two Update * Update translations to use map type - thankyou to kempeng for spotting this * Change pair method name from Display -> Format for better readability * Fixes misspelling and tests * Implement requested changes from GloriousCode * Remove reduntant function and streamlined return in currency_translation.go * Revert pair method naming conventions * Change currency naming conventions * Changed code type to exported Item type with underlying string to reduce complexity * Added interim orderbook process method to orderbook.Base type * Changed feebuilder struct field to currency.Pair * Adds fall over system for backup fx providers * deprecate function and children and fix linter issue with btcmarkets * Fixed requested changes * Fix bug and move mtx for rates * Fixed after rebase oopsies * Fix linter issues * Fixes race conditions in testing functions * Final phase coinmarketcap update * fix linter issues * Implement requested changes * Adds configuration variables to increase/decrease time durations between updating currency file and fetching new currency rates * Add a collection of tests to improve codecov * After rebase oopsy fixes for btse * Fix requested changes * fix after rebase oopsies and add more efficient comparison checks within currency pair * Fix linter issues
This commit is contained in:
committed by
Adrian Gallagher
parent
ed760e184e
commit
0990f9d118
@@ -102,7 +102,7 @@ func (b *Base) GetTicker(exchangeName string) string {
|
||||
for i := range tickerPrices {
|
||||
packagedTickers = append(packagedTickers, fmt.Sprintf(
|
||||
"Currency Pair: %s Ask: %f, Bid: %f High: %f Last: %f Low: %f ATH: %f Volume: %f",
|
||||
tickerPrices[i].CurrencyPair,
|
||||
tickerPrices[i].Pair,
|
||||
tickerPrices[i].Ask,
|
||||
tickerPrices[i].Bid,
|
||||
tickerPrices[i].High,
|
||||
|
||||
@@ -80,7 +80,7 @@ func (c IComm) StageTickerData(exchangeName, assetType string, tickerPrice *tick
|
||||
TickerStaged[exchangeName][assetType] = make(map[string]ticker.Price)
|
||||
}
|
||||
|
||||
TickerStaged[exchangeName][assetType][tickerPrice.CurrencyPair] = *tickerPrice
|
||||
TickerStaged[exchangeName][assetType][tickerPrice.Pair.String()] = *tickerPrice
|
||||
}
|
||||
|
||||
// StageOrderbookData stages updated orderbook data for the communications
|
||||
@@ -97,12 +97,11 @@ func (c IComm) StageOrderbookData(exchangeName, assetType string, ob *orderbook.
|
||||
OrderbookStaged[exchangeName][assetType] = make(map[string]Orderbook)
|
||||
}
|
||||
|
||||
_, totalAsks := ob.CalculateTotalAsks()
|
||||
_, totalBids := ob.CalculateTotalBids()
|
||||
_, totalAsks := ob.TotalAsksAmount()
|
||||
_, totalBids := ob.TotalBidsAmount()
|
||||
|
||||
OrderbookStaged[exchangeName][assetType][ob.CurrencyPair] = Orderbook{
|
||||
CurrencyPair: ob.CurrencyPair,
|
||||
OrderbookStaged[exchangeName][assetType][ob.Pair.String()] = Orderbook{
|
||||
CurrencyPair: ob.Pair.String(),
|
||||
TotalAsks: totalAsks,
|
||||
TotalBids: totalBids,
|
||||
LastUpdated: ob.LastUpdated.String()}
|
||||
TotalBids: totalBids}
|
||||
}
|
||||
|
||||
112
config/config.go
112
config/config.go
@@ -16,7 +16,6 @@ import (
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
"github.com/thrasher-/gocryptotrader/portfolio"
|
||||
)
|
||||
@@ -114,8 +113,8 @@ type Config struct {
|
||||
|
||||
// Deprecated config settings, will be removed at a future date
|
||||
CurrencyPairFormat *CurrencyPairFormatConfig `json:"currencyPairFormat,omitempty"`
|
||||
FiatDisplayCurrency string `json:"fiatDispayCurrency,omitempty"`
|
||||
Cryptocurrencies string `json:"cryptocurrencies,omitempty"`
|
||||
FiatDisplayCurrency currency.Code `json:"fiatDispayCurrency,omitempty"`
|
||||
Cryptocurrencies currency.Currencies `json:"cryptocurrencies,omitempty"`
|
||||
SMS *SMSGlobalConfig `json:"smsGlobal,omitempty"`
|
||||
}
|
||||
|
||||
@@ -143,9 +142,9 @@ type ExchangeConfig struct {
|
||||
ProxyAddress string `json:"proxyAddress"`
|
||||
WebsocketURL string `json:"websocketUrl"`
|
||||
ClientID string `json:"clientId,omitempty"`
|
||||
AvailablePairs string `json:"availablePairs"`
|
||||
EnabledPairs string `json:"enabledPairs"`
|
||||
BaseCurrencies string `json:"baseCurrencies"`
|
||||
AvailablePairs currency.Pairs `json:"availablePairs"`
|
||||
EnabledPairs currency.Pairs `json:"enabledPairs"`
|
||||
BaseCurrencies currency.Currencies `json:"baseCurrencies"`
|
||||
AssetTypes string `json:"assetTypes"`
|
||||
SupportsAutoPairUpdates bool `json:"supportsAutoPairUpdates"`
|
||||
PairsLastUpdated int64 `json:"pairsLastUpdated,omitempty"`
|
||||
@@ -178,11 +177,13 @@ type BankTransaction struct {
|
||||
|
||||
// CurrencyConfig holds all the information needed for currency related manipulation
|
||||
type CurrencyConfig struct {
|
||||
ForexProviders []base.Settings `json:"forexProviders"`
|
||||
CryptocurrencyProvider CryptocurrencyProvider `json:"cryptocurrencyProvider"`
|
||||
Cryptocurrencies string `json:"cryptocurrencies"`
|
||||
CurrencyPairFormat *CurrencyPairFormatConfig `json:"currencyPairFormat"`
|
||||
FiatDisplayCurrency string `json:"fiatDisplayCurrency"`
|
||||
ForexProviders []base.Settings `json:"forexProviders"`
|
||||
CryptocurrencyProvider CryptocurrencyProvider `json:"cryptocurrencyProvider"`
|
||||
Cryptocurrencies currency.Currencies `json:"cryptocurrencies"`
|
||||
CurrencyPairFormat *CurrencyPairFormatConfig `json:"currencyPairFormat"`
|
||||
FiatDisplayCurrency currency.Code `json:"fiatDisplayCurrency"`
|
||||
CurrencyFileUpdateDuration time.Duration `json:"currencyFileUpdateDuration"`
|
||||
ForeignExchangeUpdateDuration time.Duration `json:"foreignExchangeUpdateDuration"`
|
||||
}
|
||||
|
||||
// CryptocurrencyProvider defines coinmarketcap tools
|
||||
@@ -539,10 +540,10 @@ func (c *Config) CheckPairConsistency(exchName string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var pairs, pairsRemoved []pair.CurrencyPair
|
||||
var pairs, pairsRemoved currency.Pairs
|
||||
update := false
|
||||
for x := range enabledPairs {
|
||||
if !pair.Contains(availPairs, enabledPairs[x], true) {
|
||||
if !availPairs.Contains(enabledPairs[x], true) {
|
||||
update = true
|
||||
pairsRemoved = append(pairsRemoved, enabledPairs[x])
|
||||
continue
|
||||
@@ -560,10 +561,13 @@ func (c *Config) CheckPairConsistency(exchName string) error {
|
||||
}
|
||||
|
||||
if len(pairs) == 0 {
|
||||
exchCfg.EnabledPairs = pair.RandomPairFromPairs(availPairs).Pair().String()
|
||||
log.Debugf("Exchange %s: No enabled pairs found in available pairs, randomly added %v\n", exchName, exchCfg.EnabledPairs)
|
||||
exchCfg.EnabledPairs = append(exchCfg.EnabledPairs,
|
||||
availPairs.GetRandomPair())
|
||||
log.Debugf("Exchange %s: No enabled pairs found in available pairs, randomly added %v\n",
|
||||
exchName,
|
||||
exchCfg.EnabledPairs)
|
||||
} else {
|
||||
exchCfg.EnabledPairs = common.JoinStrings(pair.PairsToStringArray(pairs), ",")
|
||||
exchCfg.EnabledPairs = pairs
|
||||
}
|
||||
|
||||
err = c.UpdateExchangeConfig(&exchCfg)
|
||||
@@ -571,44 +575,44 @@ func (c *Config) CheckPairConsistency(exchName string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Exchange %s: Removing enabled pair(s) %v from enabled pairs as it isn't an available pair", exchName, pair.PairsToStringArray(pairsRemoved))
|
||||
log.Debugf("Exchange %s: Removing enabled pair(s) %v from enabled pairs as it isn't an available pair",
|
||||
exchName,
|
||||
pairsRemoved.Strings())
|
||||
return nil
|
||||
}
|
||||
|
||||
// SupportsPair returns true or not whether the exchange supports the supplied
|
||||
// pair
|
||||
func (c *Config) SupportsPair(exchName string, p pair.CurrencyPair) (bool, error) {
|
||||
func (c *Config) SupportsPair(exchName string, p currency.Pair) (bool, error) {
|
||||
pairs, err := c.GetAvailablePairs(exchName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return pair.Contains(pairs, p, false), nil
|
||||
return pairs.Contains(p, false), nil
|
||||
}
|
||||
|
||||
// GetAvailablePairs returns a list of currency pairs for a specifc exchange
|
||||
func (c *Config) GetAvailablePairs(exchName string) ([]pair.CurrencyPair, error) {
|
||||
func (c *Config) GetAvailablePairs(exchName string) (currency.Pairs, error) {
|
||||
exchCfg, err := c.GetExchangeConfig(exchName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pairs := pair.FormatPairs(common.SplitStrings(exchCfg.AvailablePairs, ","),
|
||||
exchCfg.ConfigCurrencyPairFormat.Delimiter,
|
||||
exchCfg.ConfigCurrencyPairFormat.Index)
|
||||
return pairs, nil
|
||||
return exchCfg.AvailablePairs.Format(exchCfg.ConfigCurrencyPairFormat.Delimiter,
|
||||
exchCfg.ConfigCurrencyPairFormat.Index,
|
||||
exchCfg.ConfigCurrencyPairFormat.Uppercase), nil
|
||||
}
|
||||
|
||||
// GetEnabledPairs returns a list of currency pairs for a specifc exchange
|
||||
func (c *Config) GetEnabledPairs(exchName string) ([]pair.CurrencyPair, error) {
|
||||
func (c *Config) GetEnabledPairs(exchName string) (currency.Pairs, error) {
|
||||
exchCfg, err := c.GetExchangeConfig(exchName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pairs := pair.FormatPairs(common.SplitStrings(exchCfg.EnabledPairs, ","),
|
||||
exchCfg.ConfigCurrencyPairFormat.Delimiter,
|
||||
exchCfg.ConfigCurrencyPairFormat.Index)
|
||||
return pairs, nil
|
||||
return exchCfg.AvailablePairs.Format(exchCfg.ConfigCurrencyPairFormat.Delimiter,
|
||||
exchCfg.ConfigCurrencyPairFormat.Index,
|
||||
exchCfg.ConfigCurrencyPairFormat.Uppercase), nil
|
||||
}
|
||||
|
||||
// GetEnabledExchanges returns a list of enabled exchanges
|
||||
@@ -758,13 +762,13 @@ func (c *Config) CheckExchangeConfigValues() error {
|
||||
if exch.Name == "" {
|
||||
return fmt.Errorf(ErrExchangeNameEmpty, i)
|
||||
}
|
||||
if exch.AvailablePairs == "" {
|
||||
if len(exch.AvailablePairs) == 0 {
|
||||
return fmt.Errorf(ErrExchangeAvailablePairsEmpty, exch.Name)
|
||||
}
|
||||
if exch.EnabledPairs == "" {
|
||||
if len(exch.EnabledPairs) == 0 {
|
||||
return fmt.Errorf(ErrExchangeEnabledPairsEmpty, exch.Name)
|
||||
}
|
||||
if exch.BaseCurrencies == "" {
|
||||
if len(exch.BaseCurrencies) == 0 {
|
||||
return fmt.Errorf(ErrExchangeBaseCurrenciesEmpty, exch.Name)
|
||||
}
|
||||
if exch.AuthenticatedAPISupport { // non-fatal error
|
||||
@@ -962,12 +966,12 @@ func (c *Config) CheckCurrencyConfigValues() error {
|
||||
}
|
||||
}
|
||||
|
||||
if c.Currency.Cryptocurrencies == "" {
|
||||
if c.Cryptocurrencies != "" {
|
||||
if c.Currency.Cryptocurrencies.Join() == "" {
|
||||
if c.Cryptocurrencies.Join() != "" {
|
||||
c.Currency.Cryptocurrencies = c.Cryptocurrencies
|
||||
c.Cryptocurrencies = ""
|
||||
c.Cryptocurrencies = nil
|
||||
} else {
|
||||
c.Currency.Cryptocurrencies = currency.DefaultCryptoCurrencies
|
||||
c.Currency.Cryptocurrencies = currency.GetDefaultCryptocurrencies()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,12 +987,12 @@ func (c *Config) CheckCurrencyConfigValues() error {
|
||||
}
|
||||
}
|
||||
|
||||
if c.Currency.FiatDisplayCurrency == "" {
|
||||
if c.FiatDisplayCurrency != "" {
|
||||
if c.Currency.FiatDisplayCurrency.IsEmpty() {
|
||||
if c.FiatDisplayCurrency.IsEmpty() {
|
||||
c.Currency.FiatDisplayCurrency = c.FiatDisplayCurrency
|
||||
c.FiatDisplayCurrency = ""
|
||||
c.FiatDisplayCurrency = currency.NewCode("")
|
||||
} else {
|
||||
c.Currency.FiatDisplayCurrency = "USD"
|
||||
c.Currency.FiatDisplayCurrency = currency.USD
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -997,24 +1001,24 @@ func (c *Config) CheckCurrencyConfigValues() error {
|
||||
// RetrieveConfigCurrencyPairs splits, assigns and verifies enabled currency
|
||||
// pairs either cryptoCurrencies or fiatCurrencies
|
||||
func (c *Config) RetrieveConfigCurrencyPairs(enabledOnly bool) error {
|
||||
cryptoCurrencies := common.SplitStrings(c.Cryptocurrencies, ",")
|
||||
fiatCurrencies := common.SplitStrings(currency.DefaultCurrencies, ",")
|
||||
cryptoCurrencies := c.Currency.Cryptocurrencies
|
||||
fiatCurrencies := currency.GetFiatCurrencies()
|
||||
|
||||
for x := range c.Exchanges {
|
||||
if !c.Exchanges[x].Enabled && enabledOnly {
|
||||
continue
|
||||
}
|
||||
|
||||
baseCurrencies := common.SplitStrings(c.Exchanges[x].BaseCurrencies, ",")
|
||||
baseCurrencies := c.Exchanges[x].BaseCurrencies
|
||||
for y := range baseCurrencies {
|
||||
if !common.StringDataCompare(fiatCurrencies, common.StringToUpper(baseCurrencies[y])) {
|
||||
fiatCurrencies = append(fiatCurrencies, common.StringToUpper(baseCurrencies[y]))
|
||||
if !fiatCurrencies.Contains(baseCurrencies[y]) {
|
||||
fiatCurrencies = append(fiatCurrencies, baseCurrencies[y])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for x := range c.Exchanges {
|
||||
var pairs []pair.CurrencyPair
|
||||
var pairs []currency.Pair
|
||||
var err error
|
||||
if !c.Exchanges[x].Enabled && enabledOnly {
|
||||
pairs, err = c.GetEnabledPairs(c.Exchanges[x].Name)
|
||||
@@ -1027,20 +1031,20 @@ func (c *Config) RetrieveConfigCurrencyPairs(enabledOnly bool) error {
|
||||
}
|
||||
|
||||
for y := range pairs {
|
||||
if !common.StringDataCompare(fiatCurrencies, pairs[y].FirstCurrency.Upper().String()) &&
|
||||
!common.StringDataCompare(cryptoCurrencies, pairs[y].FirstCurrency.Upper().String()) {
|
||||
cryptoCurrencies = append(cryptoCurrencies, pairs[y].FirstCurrency.Upper().String())
|
||||
if !fiatCurrencies.Contains(pairs[y].Base) &&
|
||||
!cryptoCurrencies.Contains(pairs[y].Base) {
|
||||
cryptoCurrencies = append(cryptoCurrencies, pairs[y].Base)
|
||||
}
|
||||
|
||||
if !common.StringDataCompare(fiatCurrencies, pairs[y].SecondCurrency.Upper().String()) &&
|
||||
!common.StringDataCompare(cryptoCurrencies, pairs[y].SecondCurrency.Upper().String()) {
|
||||
cryptoCurrencies = append(cryptoCurrencies, pairs[y].SecondCurrency.Upper().String())
|
||||
if !fiatCurrencies.Contains(pairs[y].Quote) &&
|
||||
!cryptoCurrencies.Contains(pairs[y].Quote) {
|
||||
cryptoCurrencies = append(cryptoCurrencies, pairs[y].Quote)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currency.Update(fiatCurrencies, false)
|
||||
currency.Update(cryptoCurrencies, true)
|
||||
currency.UpdateCurrencies(fiatCurrencies, false)
|
||||
currency.UpdateCurrencies(cryptoCurrencies, true)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
@@ -304,8 +304,8 @@ func TestCheckPairConsistency(t *testing.T) {
|
||||
cfg.Exchanges = append(cfg.Exchanges, ExchangeConfig{
|
||||
Name: "TestExchange",
|
||||
Enabled: true,
|
||||
AvailablePairs: "DOGE_USD,DOGE_AUD",
|
||||
EnabledPairs: "DOGE_USD,DOGE_AUD,DOGE_BTC",
|
||||
AvailablePairs: currency.NewPairsFromStrings([]string{"DOGE_USD,DOGE_AUD"}),
|
||||
EnabledPairs: currency.NewPairsFromStrings([]string{"DOGE_USD,DOGE_AUD,DOGE_BTC"}),
|
||||
ConfigCurrencyPairFormat: &CurrencyPairFormatConfig{
|
||||
Uppercase: true,
|
||||
Delimiter: "_",
|
||||
@@ -326,7 +326,7 @@ func TestCheckPairConsistency(t *testing.T) {
|
||||
t.Error("Test failed. CheckPairConsistency error:", err)
|
||||
}
|
||||
|
||||
tec.EnabledPairs = "DOGE_LTC,BTC_LTC"
|
||||
tec.EnabledPairs = currency.NewPairsFromStrings([]string{"DOGE_LTC,BTC_LTC"})
|
||||
err = cfg.UpdateExchangeConfig(&tec)
|
||||
if err != nil {
|
||||
t.Error("Test failed. CheckPairConsistency Update config failed, error:", err)
|
||||
@@ -347,14 +347,16 @@ func TestSupportsPair(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
_, err = cfg.SupportsPair("asdf", pair.NewCurrencyPair("BTC", "USD"))
|
||||
_, err = cfg.SupportsPair("asdf",
|
||||
currency.NewPair(currency.BTC, currency.USD))
|
||||
if err == nil {
|
||||
t.Error(
|
||||
"Test failed. TestSupportsPair. Non-existent exchange returned nil error",
|
||||
)
|
||||
}
|
||||
|
||||
_, err = cfg.SupportsPair("Bitfinex", pair.NewCurrencyPair("BTC", "USD"))
|
||||
_, err = cfg.SupportsPair("Bitfinex",
|
||||
currency.NewPair(currency.BTC, currency.USD))
|
||||
if err != nil {
|
||||
t.Errorf(
|
||||
"Test failed. TestSupportsPair. Incorrect values. Err: %s", err,
|
||||
@@ -687,7 +689,7 @@ func TestCheckExchangeConfigValues(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
checkExchangeConfigValues.Exchanges[0].BaseCurrencies = ""
|
||||
checkExchangeConfigValues.Exchanges[0].BaseCurrencies = currency.NewCurrenciesFromStringArray([]string{""})
|
||||
err = checkExchangeConfigValues.CheckExchangeConfigValues()
|
||||
if err == nil {
|
||||
t.Errorf(
|
||||
@@ -695,7 +697,7 @@ func TestCheckExchangeConfigValues(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
checkExchangeConfigValues.Exchanges[0].EnabledPairs = ""
|
||||
checkExchangeConfigValues.Exchanges[0].EnabledPairs = currency.NewPairsFromStrings([]string{""})
|
||||
err = checkExchangeConfigValues.CheckExchangeConfigValues()
|
||||
if err == nil {
|
||||
t.Errorf(
|
||||
@@ -703,7 +705,7 @@ func TestCheckExchangeConfigValues(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
checkExchangeConfigValues.Exchanges[0].AvailablePairs = ""
|
||||
checkExchangeConfigValues.Exchanges[0].AvailablePairs = currency.NewPairsFromStrings([]string{""})
|
||||
err = checkExchangeConfigValues.CheckExchangeConfigValues()
|
||||
if err == nil {
|
||||
t.Errorf(
|
||||
@@ -719,7 +721,7 @@ func TestCheckExchangeConfigValues(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
checkExchangeConfigValues.Cryptocurrencies = ""
|
||||
checkExchangeConfigValues.Cryptocurrencies = currency.NewCurrenciesFromStringArray([]string{""})
|
||||
err = checkExchangeConfigValues.CheckExchangeConfigValues()
|
||||
if err == nil {
|
||||
t.Errorf(
|
||||
@@ -728,7 +730,7 @@ func TestCheckExchangeConfigValues(t *testing.T) {
|
||||
}
|
||||
|
||||
checkExchangeConfigValues.Exchanges = checkExchangeConfigValues.Exchanges[:0]
|
||||
checkExchangeConfigValues.Cryptocurrencies = "TESTYTEST"
|
||||
checkExchangeConfigValues.Cryptocurrencies = currency.NewCurrenciesFromStringArray([]string{"TESTYTEST"})
|
||||
err = checkExchangeConfigValues.CheckExchangeConfigValues()
|
||||
if err == nil {
|
||||
t.Errorf(
|
||||
@@ -924,12 +926,12 @@ func TestUpdateConfig(t *testing.T) {
|
||||
t.Fatalf("Test failed. Error should of been thrown for invalid path")
|
||||
}
|
||||
|
||||
newCfg.Currency.Cryptocurrencies = ""
|
||||
newCfg.Currency.Cryptocurrencies = currency.NewCurrenciesFromStringArray([]string{""})
|
||||
err = c.UpdateConfig(ConfigTestFile, newCfg)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed. %s", err)
|
||||
}
|
||||
if c.Currency.Cryptocurrencies == "" {
|
||||
if c.Currency.Cryptocurrencies.Join() == "" {
|
||||
t.Fatalf("Test failed. Cryptocurrencies should have been repopulated")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,9 @@
|
||||
"uppercase": true,
|
||||
"delimiter": "-"
|
||||
},
|
||||
"fiatDisplayCurrency": "USD"
|
||||
"fiatDisplayCurrency": "USD",
|
||||
"currencyFileUpdateDuration": 0,
|
||||
"foreignExchangeUpdateDuration": 0
|
||||
},
|
||||
"communications": {
|
||||
"slack": {
|
||||
|
||||
2102
currency/code.go
Normal file
2102
currency/code.go
Normal file
File diff suppressed because it is too large
Load Diff
426
currency/code_test.go
Normal file
426
currency/code_test.go
Normal file
@@ -0,0 +1,426 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
func TestRoleString(t *testing.T) {
|
||||
if Unset.String() != UnsetRollString {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
UnsetRollString,
|
||||
Unset)
|
||||
}
|
||||
|
||||
if Fiat.String() != FiatCurrencyString {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
FiatCurrencyString,
|
||||
Fiat)
|
||||
}
|
||||
|
||||
if Cryptocurrency.String() != CryptocurrencyString {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
CryptocurrencyString,
|
||||
Cryptocurrency)
|
||||
}
|
||||
|
||||
if Token.String() != TokenString {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
TokenString,
|
||||
Token)
|
||||
}
|
||||
|
||||
if Contract.String() != ContractString {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
ContractString,
|
||||
Contract)
|
||||
}
|
||||
|
||||
var random Role = 1 << 7
|
||||
|
||||
if random.String() != "UNKNOWN" {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
"UNKNOWN",
|
||||
random)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoleMarshalJSON(t *testing.T) {
|
||||
d, err := common.JSONEncode(Fiat)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Role MarshalJSON() error", err)
|
||||
}
|
||||
|
||||
expected := `"fiatCurrency"`
|
||||
if string(d) != expected {
|
||||
t.Errorf("Test Failed - Role MarshalJSON() error expected %s but recieved %s",
|
||||
expected,
|
||||
string(d))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoleUnmarshalJSON(t *testing.T) {
|
||||
type AllTheRoles struct {
|
||||
RoleOne Role `json:"RoleOne"`
|
||||
RoleTwo Role `json:"RoleTwo"`
|
||||
RoleThree Role `json:"RoleThree"`
|
||||
RoleFour Role `json:"RoleFour"`
|
||||
RoleFive Role `json:"RoleFive"`
|
||||
RoleUnknown Role `json:"RoleUnknown"`
|
||||
}
|
||||
|
||||
var outgoing = AllTheRoles{
|
||||
RoleOne: Unset,
|
||||
RoleTwo: Cryptocurrency,
|
||||
RoleThree: Fiat,
|
||||
RoleFour: Token,
|
||||
RoleFive: Contract,
|
||||
}
|
||||
|
||||
e, err := common.JSONEncode(1337)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Role UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
var incoming AllTheRoles
|
||||
err = common.JSONDecode(e, &incoming)
|
||||
if err == nil {
|
||||
t.Fatal("Test Failed - Role UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
e, err = common.JSONEncode(outgoing)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Role UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
err = common.JSONDecode(e, &incoming)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Role UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
if incoming.RoleOne != Unset {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
Unset,
|
||||
incoming.RoleOne)
|
||||
}
|
||||
|
||||
if incoming.RoleTwo != Cryptocurrency {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
Cryptocurrency,
|
||||
incoming.RoleTwo)
|
||||
}
|
||||
|
||||
if incoming.RoleThree != Fiat {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
Fiat,
|
||||
incoming.RoleThree)
|
||||
}
|
||||
|
||||
if incoming.RoleFour != Token {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
Token,
|
||||
incoming.RoleFour)
|
||||
}
|
||||
|
||||
if incoming.RoleFive != Contract {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
Contract,
|
||||
incoming.RoleFive)
|
||||
}
|
||||
|
||||
if incoming.RoleUnknown != Unset {
|
||||
t.Errorf("Test Failed - Role String() error expected %s but recieved %s",
|
||||
incoming.RoleFive,
|
||||
incoming.RoleUnknown)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseCode(t *testing.T) {
|
||||
var main BaseCodes
|
||||
if main.HasData() {
|
||||
t.Errorf("Test Failed - BaseCode HasData() error expected false but recieved %v",
|
||||
main.HasData())
|
||||
}
|
||||
|
||||
catsCode := main.Register("CATS")
|
||||
if !main.HasData() {
|
||||
t.Errorf("Test Failed - BaseCode HasData() error expected true but recieved %v",
|
||||
main.HasData())
|
||||
}
|
||||
|
||||
if !main.Register("CATS").Match(catsCode) {
|
||||
t.Errorf("Test Failed - BaseCode Match() error expected true but recieved %v",
|
||||
false)
|
||||
}
|
||||
|
||||
if main.Register("DOGS").Match(catsCode) {
|
||||
t.Errorf("Test Failed - BaseCode Match() error expected false but recieved %v",
|
||||
true)
|
||||
}
|
||||
|
||||
loadedCurrencies := main.GetCurrencies()
|
||||
|
||||
if loadedCurrencies.Contains(main.Register("OWLS")) {
|
||||
t.Errorf("Test Failed - BaseCode Contains() error expected false but recieved %v",
|
||||
true)
|
||||
}
|
||||
|
||||
if !loadedCurrencies.Contains(catsCode) {
|
||||
t.Errorf("Test Failed - BaseCode Contains() error expected true but recieved %v",
|
||||
false)
|
||||
}
|
||||
|
||||
err := main.UpdateContract("Bitcoin Perpetual", "XBTUSD", "Bitmex")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - BaseCode UpdateContract error", err)
|
||||
}
|
||||
|
||||
err = main.UpdateCryptocurrency("Bitcoin", "BTC", 1337)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - BaseCode UpdateContract error", err)
|
||||
}
|
||||
|
||||
err = main.UpdateFiatCurrency("Australian Dollar", "AUD", 1336)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - BaseCode UpdateContract error", err)
|
||||
}
|
||||
|
||||
err = main.UpdateToken("Populous", "PPT", "ETH", 1335)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - BaseCode UpdateContract error", err)
|
||||
}
|
||||
|
||||
contract := main.Register("XBTUSD")
|
||||
|
||||
if contract.IsFiatCurrency() {
|
||||
t.Errorf("Test Failed - BaseCode IsFiatCurrency() error expected false but recieved %v",
|
||||
true)
|
||||
}
|
||||
|
||||
if contract.IsCryptocurrency() {
|
||||
t.Errorf("Test Failed - BaseCode IsFiatCurrency() error expected false but recieved %v",
|
||||
true)
|
||||
}
|
||||
|
||||
if contract.IsDefaultFiatCurrency() {
|
||||
t.Errorf("Test Failed - BaseCode IsDefaultFiatCurrency() error expected false but recieved %v",
|
||||
true)
|
||||
}
|
||||
|
||||
if contract.IsDefaultFiatCurrency() {
|
||||
t.Errorf("Test Failed - BaseCode IsFiatCurrency() error expected false but recieved %v",
|
||||
true)
|
||||
}
|
||||
|
||||
err = main.LoadItem(Item{
|
||||
ID: 0,
|
||||
FullName: "Cardano",
|
||||
Role: Cryptocurrency,
|
||||
Symbol: "ADA",
|
||||
})
|
||||
if err != nil {
|
||||
t.Error("Test Failed - BaseCode LoadItem() error", err)
|
||||
}
|
||||
|
||||
full, err := main.GetFullCurrencyData()
|
||||
if err != nil {
|
||||
t.Error("Test Failed - BaseCode GetFullCurrencyData error", err)
|
||||
}
|
||||
|
||||
if len(full.Contracts) != 1 {
|
||||
t.Errorf("Test Failed - BaseCode GetFullCurrencyData() error expected 1 but recieved %v",
|
||||
len(full.Contracts))
|
||||
}
|
||||
|
||||
if len(full.Cryptocurrency) != 2 {
|
||||
t.Errorf("Test Failed - BaseCode GetFullCurrencyData() error expected 1 but recieved %v",
|
||||
len(full.Cryptocurrency))
|
||||
}
|
||||
|
||||
if len(full.FiatCurrency) != 1 {
|
||||
t.Errorf("Test Failed - BaseCode GetFullCurrencyData() error expected 1 but recieved %v",
|
||||
len(full.FiatCurrency))
|
||||
}
|
||||
|
||||
if len(full.Token) != 1 {
|
||||
t.Errorf("Test Failed - BaseCode GetFullCurrencyData() error expected 1 but recieved %v",
|
||||
len(full.Token))
|
||||
}
|
||||
|
||||
if len(full.UnsetCurrency) != 3 {
|
||||
t.Errorf("Test Failed - BaseCode GetFullCurrencyData() error expected 3 but recieved %v",
|
||||
len(full.UnsetCurrency))
|
||||
}
|
||||
|
||||
if !full.LastMainUpdate.IsZero() {
|
||||
t.Errorf("Test Failed - BaseCode GetFullCurrencyData() error expected 0 but recieved %s",
|
||||
full.LastMainUpdate)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodeString(t *testing.T) {
|
||||
expected := "TEST"
|
||||
cc := NewCode("TEST")
|
||||
if cc.String() != expected {
|
||||
t.Errorf("Test Failed - Currency Code String() error expected %s but recieved %s",
|
||||
expected, cc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodeLower(t *testing.T) {
|
||||
expected := "test"
|
||||
cc := NewCode("TEST")
|
||||
if cc.Lower().String() != expected {
|
||||
t.Errorf("Test Failed - Currency Code Lower() error expected %s but recieved %s",
|
||||
expected,
|
||||
cc.Lower())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodeUpper(t *testing.T) {
|
||||
expected := "TEST"
|
||||
cc := NewCode("test")
|
||||
if cc.Upper().String() != expected {
|
||||
t.Errorf("Test Failed - Currency Code Upper() error expected %s but recieved %s",
|
||||
expected,
|
||||
cc.Upper())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodeUnmarshalJSON(t *testing.T) {
|
||||
var unmarshalHere Code
|
||||
expected := "BRO"
|
||||
encoded, err := common.JSONEncode(expected)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Currency Code UnmarshalJSON error", err)
|
||||
}
|
||||
|
||||
err = common.JSONDecode(encoded, &unmarshalHere)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Currency Code UnmarshalJSON error", err)
|
||||
}
|
||||
|
||||
err = common.JSONDecode(encoded, &unmarshalHere)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Currency Code UnmarshalJSON error", err)
|
||||
}
|
||||
|
||||
if unmarshalHere.String() != expected {
|
||||
t.Errorf("Test Failed - Currency Code Upper() error expected %s but recieved %s",
|
||||
expected,
|
||||
unmarshalHere)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodeMarshalJSON(t *testing.T) {
|
||||
quickstruct := struct {
|
||||
Codey Code `json:"sweetCodes"`
|
||||
}{
|
||||
Codey: NewCode("BRO"),
|
||||
}
|
||||
|
||||
expectedJSON := `{"sweetCodes":"BRO"}`
|
||||
|
||||
encoded, err := common.JSONEncode(quickstruct)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Currency Code UnmarshalJSON error", err)
|
||||
}
|
||||
|
||||
if string(encoded) != expectedJSON {
|
||||
t.Errorf("Test Failed - Currency Code Upper() error expected %s but recieved %s",
|
||||
expectedJSON,
|
||||
string(encoded))
|
||||
}
|
||||
|
||||
quickstruct = struct {
|
||||
Codey Code `json:"sweetCodes"`
|
||||
}{
|
||||
Codey: Code{}, // nil code
|
||||
}
|
||||
|
||||
encoded, err = common.JSONEncode(quickstruct)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Currency Code UnmarshalJSON error", err)
|
||||
}
|
||||
|
||||
newExpectedJSON := `{"sweetCodes":""}`
|
||||
if string(encoded) != newExpectedJSON {
|
||||
t.Errorf("Test Failed - Currency Code Upper() error expected %s but recieved %s",
|
||||
newExpectedJSON, string(encoded))
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDefaultCurrency(t *testing.T) {
|
||||
if !USD.IsDefaultFiatCurrency() {
|
||||
t.Errorf("Test Failed. TestIsDefaultCurrency Cannot match currency %s.",
|
||||
USD)
|
||||
}
|
||||
if !AUD.IsDefaultFiatCurrency() {
|
||||
t.Errorf("Test Failed. TestIsDefaultCurrency Cannot match currency, %s.",
|
||||
AUD)
|
||||
}
|
||||
if LTC.IsDefaultFiatCurrency() {
|
||||
t.Errorf("Test Failed. TestIsDefaultCurrency Function return is incorrect with, %s.",
|
||||
LTC)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDefaultCryptocurrency(t *testing.T) {
|
||||
if !BTC.IsDefaultCryptocurrency() {
|
||||
t.Errorf("Test Failed. TestIsDefaultCryptocurrency cannot match currency, %s.",
|
||||
BTC)
|
||||
}
|
||||
if !LTC.IsDefaultCryptocurrency() {
|
||||
t.Errorf("Test Failed. TestIsDefaultCryptocurrency cannot match currency, %s.",
|
||||
LTC)
|
||||
}
|
||||
if AUD.IsDefaultCryptocurrency() {
|
||||
t.Errorf("Test Failed. TestIsDefaultCryptocurrency function return is incorrect with, %s.",
|
||||
AUD)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsFiatCurrency(t *testing.T) {
|
||||
if !USD.IsFiatCurrency() {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsFiatCurrency cannot match currency, %s.", USD)
|
||||
}
|
||||
if !CNY.IsFiatCurrency() {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsFiatCurrency cannot match currency, %s.", CNY)
|
||||
}
|
||||
if LINO.IsFiatCurrency() {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsFiatCurrency cannot match currency, %s.", LINO,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCryptocurrency(t *testing.T) {
|
||||
if !BTC.IsCryptocurrency() {
|
||||
t.Errorf("Test Failed. TestIsFiatCurrency cannot match currency, %s.",
|
||||
BTC)
|
||||
}
|
||||
if !LTC.IsCryptocurrency() {
|
||||
t.Errorf("Test Failed. TestIsFiatCurrency cannot match currency, %s.",
|
||||
LTC)
|
||||
}
|
||||
if AUD.IsCryptocurrency() {
|
||||
t.Errorf("Test Failed. TestIsFiatCurrency cannot match currency, %s.",
|
||||
AUD)
|
||||
}
|
||||
}
|
||||
|
||||
func TestItemString(t *testing.T) {
|
||||
expected := "Hello,World"
|
||||
newItem := Item{
|
||||
FullName: expected,
|
||||
}
|
||||
|
||||
if newItem.String() != expected {
|
||||
t.Errorf("Test Failed - Item String() error expected %s but recieved %s",
|
||||
expected,
|
||||
newItem)
|
||||
}
|
||||
}
|
||||
@@ -71,14 +71,20 @@ type CryptoCurrencyInfo map[string]struct {
|
||||
|
||||
// CryptoCurrencyMap defines a cryptocurrency struct
|
||||
type CryptoCurrencyMap struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Symbol string `json:"symbol"`
|
||||
Slug string `json:"slug"`
|
||||
IsActive int `json:"is_active"`
|
||||
FirstHistoricalData time.Time `json:"first_historical_data"`
|
||||
LastHistoricalData time.Time `json:"last_historical_data"`
|
||||
Platform interface{} `json:"platform"`
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Symbol string `json:"symbol"`
|
||||
Slug string `json:"slug"`
|
||||
IsActive int `json:"is_active"`
|
||||
FirstHistoricalData time.Time `json:"first_historical_data"`
|
||||
LastHistoricalData time.Time `json:"last_historical_data"`
|
||||
Platform struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Symbol string `json:"symbol"`
|
||||
Slug string `json:"slug"`
|
||||
TokenAddress string `json:"token_address"`
|
||||
} `json:"platform"`
|
||||
}
|
||||
|
||||
// CryptocurrencyHistoricalListings defines a historical listing data
|
||||
|
||||
361
currency/conversion.go
Normal file
361
currency/conversion.go
Normal file
@@ -0,0 +1,361 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
// ConversionRates defines protected conversion rate map for concurrent updating
|
||||
// and retrieval of foreign exchange rates for mainly fiat currencies
|
||||
type ConversionRates struct {
|
||||
m map[*Item]map[*Item]*float64
|
||||
mtx sync.Mutex
|
||||
}
|
||||
|
||||
// HasData returns if conversion rates are present
|
||||
func (c *ConversionRates) HasData() bool {
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
if c.m == nil {
|
||||
return false
|
||||
}
|
||||
return len(c.m) != 0
|
||||
}
|
||||
|
||||
// GetRate returns a rate from the conversion rate list
|
||||
func (c *ConversionRates) GetRate(from, to Code) (float64, error) {
|
||||
if from.Item == USDT.Item {
|
||||
from = USD
|
||||
}
|
||||
|
||||
if to.Item == USDT.Item {
|
||||
to = USD
|
||||
}
|
||||
|
||||
if from.Item == RUR.Item {
|
||||
from = RUB
|
||||
}
|
||||
|
||||
if to.Item == RUR.Item {
|
||||
to = RUB
|
||||
}
|
||||
|
||||
if from.Item == to.Item {
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
|
||||
p, ok := c.m[from.Item][to.Item]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("rate not found for from %s to %s conversion",
|
||||
from,
|
||||
to)
|
||||
}
|
||||
|
||||
return *p, nil
|
||||
}
|
||||
|
||||
// Register registers a new conversion rate if not found adds it and allows for
|
||||
// quick updates
|
||||
func (c *ConversionRates) Register(from, to Code) (Conversion, error) {
|
||||
if from.IsCryptocurrency() {
|
||||
return Conversion{}, errors.New("from currency is a cryptocurrency value")
|
||||
}
|
||||
|
||||
if to.IsCryptocurrency() {
|
||||
return Conversion{}, errors.New("to currency is a cryptocurrency value")
|
||||
}
|
||||
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
|
||||
p, ok := c.m[from.Item][to.Item]
|
||||
if !ok {
|
||||
log.Errorf("currency conversion rate not found from %s to %s", from, to)
|
||||
return Conversion{}, errors.New("no rate found")
|
||||
}
|
||||
|
||||
i, ok := c.m[to.Item][from.Item]
|
||||
if !ok {
|
||||
log.Errorf("currency conversion inversion rate not found from %s to %s",
|
||||
to,
|
||||
from)
|
||||
return Conversion{}, errors.New("no rate found")
|
||||
}
|
||||
|
||||
return Conversion{From: from, To: to, rate: p, mtx: &c.mtx, inverseRate: i},
|
||||
nil
|
||||
}
|
||||
|
||||
// Update updates the full conversion rate values including inversion and
|
||||
// cross rates
|
||||
func (c *ConversionRates) Update(m map[string]float64) error {
|
||||
if len(m) == 0 {
|
||||
return errors.New("no data given")
|
||||
}
|
||||
|
||||
if storage.IsVerbose() {
|
||||
log.Debug("Conversion rates are being updated.")
|
||||
}
|
||||
|
||||
solidvalues := make(map[Code]map[Code]float64)
|
||||
|
||||
var list []Code // Verification list, cross check all currencies coming in
|
||||
|
||||
var mainBaseCurrency Code
|
||||
|
||||
for key, val := range m {
|
||||
code1, err := storage.ValidateFiatCode(key[:3])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mainBaseCurrency == (Code{}) {
|
||||
mainBaseCurrency = code1
|
||||
}
|
||||
|
||||
code2, err := storage.ValidateFiatCode(key[3:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if code1 == code2 { // Get rid of same conversions
|
||||
continue
|
||||
}
|
||||
|
||||
var codeOneFound, codeTwoFound bool
|
||||
// Check and add to our funky list
|
||||
for i := range list {
|
||||
if list[i] == code1 {
|
||||
codeOneFound = true
|
||||
if codeTwoFound {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if list[i] == code2 {
|
||||
codeTwoFound = true
|
||||
if codeOneFound {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !codeOneFound {
|
||||
list = append(list, code1)
|
||||
}
|
||||
|
||||
if !codeTwoFound {
|
||||
list = append(list, code2)
|
||||
}
|
||||
|
||||
if solidvalues[code1] == nil {
|
||||
solidvalues[code1] = make(map[Code]float64)
|
||||
}
|
||||
|
||||
solidvalues[code1][code2] = val
|
||||
|
||||
// Input inverse values 1/val to swap from -> to and vice versa
|
||||
|
||||
if solidvalues[code2] == nil {
|
||||
solidvalues[code2] = make(map[Code]float64)
|
||||
}
|
||||
|
||||
solidvalues[code2][code1] = 1 / val
|
||||
}
|
||||
|
||||
for _, base := range list {
|
||||
for _, term := range list {
|
||||
if base == term {
|
||||
continue
|
||||
}
|
||||
_, ok := solidvalues[base][term]
|
||||
if !ok {
|
||||
var crossRate float64
|
||||
// Check inversion to speed things up
|
||||
v, ok := solidvalues[term][base]
|
||||
if !ok {
|
||||
v1, ok := solidvalues[mainBaseCurrency][base]
|
||||
if !ok {
|
||||
return fmt.Errorf("value not found base %s term %s",
|
||||
mainBaseCurrency,
|
||||
base)
|
||||
}
|
||||
v2, ok := solidvalues[mainBaseCurrency][term]
|
||||
if !ok {
|
||||
return fmt.Errorf("value not found base %s term %s",
|
||||
mainBaseCurrency,
|
||||
term)
|
||||
}
|
||||
crossRate = v2 / v1
|
||||
} else {
|
||||
crossRate = 1 / v
|
||||
}
|
||||
if storage.IsVerbose() {
|
||||
log.Debugf("Conversion from %s to %s deriving cross rate value %f",
|
||||
base,
|
||||
term,
|
||||
crossRate)
|
||||
}
|
||||
solidvalues[base][term] = crossRate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.m = nil
|
||||
for key, val := range solidvalues {
|
||||
for key2, val2 := range val {
|
||||
if c.m == nil {
|
||||
c.m = make(map[*Item]map[*Item]*float64)
|
||||
}
|
||||
|
||||
if c.m[key.Item] == nil {
|
||||
c.m[key.Item] = make(map[*Item]*float64)
|
||||
}
|
||||
|
||||
p := c.m[key.Item][key2.Item]
|
||||
if p == nil {
|
||||
newPalsAndFriends := val2
|
||||
c.m[key.Item][key2.Item] = &newPalsAndFriends
|
||||
} else {
|
||||
*p = val2
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFullRates returns the full conversion list
|
||||
func (c *ConversionRates) GetFullRates() Conversions {
|
||||
var conversions Conversions
|
||||
c.mtx.Lock()
|
||||
for key, val := range c.m {
|
||||
for key2, val2 := range val {
|
||||
conversions = append(conversions, Conversion{
|
||||
From: Code{Item: key},
|
||||
To: Code{Item: key2},
|
||||
rate: val2,
|
||||
mtx: &c.mtx,
|
||||
})
|
||||
}
|
||||
}
|
||||
c.mtx.Unlock()
|
||||
return conversions
|
||||
}
|
||||
|
||||
// Conversions define a list of conversion data
|
||||
type Conversions []Conversion
|
||||
|
||||
// Slice exposes the underlying Conversion slice type
|
||||
func (c Conversions) Slice() []Conversion {
|
||||
return c
|
||||
}
|
||||
|
||||
// NewConversionFromString splits a string from a foreign exchange provider
|
||||
func NewConversionFromString(p string) (Conversion, error) {
|
||||
return NewConversionFromStrings(p[:3], p[3:])
|
||||
}
|
||||
|
||||
// NewConversion returns a conversion rate object that allows for
|
||||
// obtaining efficient rate values when needed
|
||||
func NewConversion(from, to Code) (Conversion, error) {
|
||||
return storage.NewConversion(from, to)
|
||||
}
|
||||
|
||||
// NewConversionFromStrings assigns or finds a new conversion unit
|
||||
func NewConversionFromStrings(from, to string) (Conversion, error) {
|
||||
return NewConversion(NewCode(from), NewCode(to))
|
||||
}
|
||||
|
||||
// Conversion defines a specific currency conversion for a rate
|
||||
type Conversion struct {
|
||||
From Code
|
||||
To Code
|
||||
rate *float64
|
||||
inverseRate *float64
|
||||
mtx *sync.Mutex
|
||||
}
|
||||
|
||||
// IsInvalid returns true if both from and to currencies are the same
|
||||
func (c Conversion) IsInvalid() bool {
|
||||
if c.From.Item == nil || c.To.Item == nil {
|
||||
return true
|
||||
}
|
||||
return c.From.Item == c.To.Item
|
||||
}
|
||||
|
||||
// IsFiat checks to see if the from and to currency is a fiat e.g. EURUSD
|
||||
func (c Conversion) IsFiat() bool {
|
||||
return storage.IsFiatCurrency(c.From) && storage.IsFiatCurrency(c.To)
|
||||
}
|
||||
|
||||
// String returns the stringed fields
|
||||
func (c Conversion) String() string {
|
||||
return c.From.String() + c.To.String()
|
||||
}
|
||||
|
||||
// GetRate returns system rate if availabled
|
||||
func (c Conversion) GetRate() (float64, error) {
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
if c.rate == nil {
|
||||
return 0, errors.New("rate undefined")
|
||||
}
|
||||
return *c.rate, nil
|
||||
}
|
||||
|
||||
// GetInversionRate returns the rate of the inversion of the conversion pair
|
||||
func (c Conversion) GetInversionRate() (float64, error) {
|
||||
if c.mtx == nil {
|
||||
return 0, errors.New("mutex copy failure")
|
||||
}
|
||||
|
||||
c.mtx.Lock()
|
||||
defer c.mtx.Unlock()
|
||||
if c.rate == nil {
|
||||
return 0, errors.New("rate undefined")
|
||||
}
|
||||
return *c.inverseRate, nil
|
||||
}
|
||||
|
||||
// Convert for example converts $1 USD to the equivalent Japanese Yen or vice
|
||||
// versa.
|
||||
func (c Conversion) Convert(fromAmount float64) (float64, error) {
|
||||
if c.IsInvalid() {
|
||||
return fromAmount, nil
|
||||
}
|
||||
|
||||
if !c.IsFiat() {
|
||||
return 0, errors.New("not fiat pair")
|
||||
}
|
||||
|
||||
r, err := c.GetRate()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return r * fromAmount, nil
|
||||
}
|
||||
|
||||
// ConvertInverse converts backwards if needed
|
||||
func (c Conversion) ConvertInverse(fromAmount float64) (float64, error) {
|
||||
if c.IsInvalid() {
|
||||
return fromAmount, nil
|
||||
}
|
||||
|
||||
if !c.IsFiat() {
|
||||
return 0, errors.New("not fiat pair")
|
||||
}
|
||||
|
||||
r, err := c.GetInversionRate()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return r * fromAmount, nil
|
||||
}
|
||||
177
currency/conversion_test.go
Normal file
177
currency/conversion_test.go
Normal file
@@ -0,0 +1,177 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
func TestNewConversionFromString(t *testing.T) {
|
||||
expected := "AUDUSD"
|
||||
conv, err := NewConversionFromString(expected)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - NewConversionFromString() error", err)
|
||||
}
|
||||
if conv.String() != expected {
|
||||
t.Errorf("Test Failed - NewConversion() error expected %s but received %s",
|
||||
expected,
|
||||
conv)
|
||||
}
|
||||
|
||||
newexpected := common.StringToLower(expected)
|
||||
conv, err = NewConversionFromString(newexpected)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - NewConversionFromString() error", err)
|
||||
}
|
||||
if conv.String() != newexpected {
|
||||
t.Errorf("Test Failed - NewConversion() error expected %s but received %s",
|
||||
newexpected,
|
||||
conv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewConversionFromStrings(t *testing.T) {
|
||||
from := "AUD"
|
||||
to := "USD"
|
||||
expected := "AUDUSD"
|
||||
|
||||
conv, err := NewConversionFromStrings(from, to)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - NewConversionFromString() error", err)
|
||||
}
|
||||
|
||||
if conv.String() != expected {
|
||||
t.Errorf("Test Failed - NewConversion() error expected %s but received %s",
|
||||
expected,
|
||||
conv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewConversion(t *testing.T) {
|
||||
from := NewCode("AUD")
|
||||
to := NewCode("USD")
|
||||
expected := "AUDUSD"
|
||||
|
||||
conv, err := NewConversion(from, to)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - NewConversionFromCode() error", err)
|
||||
}
|
||||
|
||||
if conv.String() != expected {
|
||||
t.Errorf("Test Failed - NewConversion() error expected %s but received %s",
|
||||
expected,
|
||||
conv)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConversionIsInvalid(t *testing.T) {
|
||||
from := AUD
|
||||
to := USD
|
||||
|
||||
conv, err := NewConversion(from, to)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - NewConversion() error", err)
|
||||
}
|
||||
|
||||
if conv.IsInvalid() {
|
||||
t.Errorf("Test Failed - IsInvalid() error expected false but received %v",
|
||||
conv.IsInvalid())
|
||||
}
|
||||
|
||||
to = AUD
|
||||
conv, err = NewConversion(from, to)
|
||||
if err == nil {
|
||||
t.Fatal("Test Failed - NewConversion() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConversionIsFiatPair(t *testing.T) {
|
||||
from := AUD
|
||||
to := USD
|
||||
|
||||
conv, err := NewConversion(from, to)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - NewConversion() error", err)
|
||||
}
|
||||
|
||||
if !conv.IsFiat() {
|
||||
t.Errorf("Test Failed - IsFiatPair() error expected true but received %v",
|
||||
conv.IsFiat())
|
||||
}
|
||||
|
||||
to = LTC
|
||||
conv, err = NewConversion(from, to)
|
||||
if err == nil {
|
||||
t.Fatal("Test Failed - NewConversion() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConversionsRatesSystem(t *testing.T) {
|
||||
var SuperDuperConversionSystem ConversionRates
|
||||
|
||||
if SuperDuperConversionSystem.HasData() {
|
||||
t.Fatalf("Test Failed - HasData() error expected false but recieved %v",
|
||||
SuperDuperConversionSystem.HasData())
|
||||
}
|
||||
|
||||
testmap := map[string]float64{
|
||||
"USDAUD": 1.3969317581,
|
||||
"USDBRL": 3.7047257979,
|
||||
"USDCAD": 1.3186386881,
|
||||
"USDCHF": 1,
|
||||
"USDCNY": 6.7222712044,
|
||||
"USDCZK": 22.6406277552,
|
||||
"USDDKK": 6.5785575736,
|
||||
"USDEUR": 0.8816787163,
|
||||
"USDGBP": 0.7665755599,
|
||||
"USDHKD": 7.8492329395,
|
||||
"USDILS": 3.6152354082,
|
||||
"USDINR": 71.154558279,
|
||||
"USDJPY": 110.7476635514,
|
||||
"USDKRW": 1122.7913948157,
|
||||
"USDMXN": 19.1589666725,
|
||||
"USDNOK": 8.5818197849,
|
||||
"USDNZD": 1.4559160642,
|
||||
"USDPLN": 3.8304531829,
|
||||
"USDRUB": 65.7533062952,
|
||||
"USDSEK": 9.3196085346,
|
||||
"USDSGD": 1.3512608006,
|
||||
"USDTHB": 31.0950449656,
|
||||
"USDZAR": 14.138070887,
|
||||
}
|
||||
|
||||
err := SuperDuperConversionSystem.Update(testmap)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Update() error", err)
|
||||
}
|
||||
|
||||
err = SuperDuperConversionSystem.Update(nil)
|
||||
if err == nil {
|
||||
t.Fatal("Test Failed - Update() error cannnot be nil")
|
||||
}
|
||||
|
||||
if !SuperDuperConversionSystem.HasData() {
|
||||
t.Fatalf("Test Failed - HasData() error expected true but recieved %v",
|
||||
SuperDuperConversionSystem.HasData())
|
||||
}
|
||||
|
||||
// * to a rate
|
||||
p := SuperDuperConversionSystem.m[USD.Item][AUD.Item]
|
||||
// inverse * to a rate
|
||||
pi := SuperDuperConversionSystem.m[AUD.Item][USD.Item]
|
||||
r := *p * 1000
|
||||
expectedRate := 1396.9317581
|
||||
if r != expectedRate {
|
||||
t.Errorf("Test Failed - Convert() error expected %.13f but recieved %.13f",
|
||||
expectedRate,
|
||||
r)
|
||||
}
|
||||
|
||||
inverseR := *pi * expectedRate
|
||||
expectedInverseRate := float64(1000)
|
||||
if inverseR != expectedInverseRate {
|
||||
t.Errorf("Test Failed - Convert() error expected %.13f but recieved %.13f",
|
||||
expectedInverseRate,
|
||||
inverseR)
|
||||
}
|
||||
}
|
||||
95
currency/currencies.go
Normal file
95
currency/currencies.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package currency
|
||||
|
||||
import "github.com/thrasher-/gocryptotrader/common"
|
||||
|
||||
// NewCurrenciesFromStringArray returns a Currencies object from strings
|
||||
func NewCurrenciesFromStringArray(currencies []string) Currencies {
|
||||
var list Currencies
|
||||
for i := range currencies {
|
||||
if currencies[i] == "" {
|
||||
continue
|
||||
}
|
||||
list = append(list, NewCode(currencies[i]))
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// Currencies define a range of supported currency codes
|
||||
type Currencies []Code
|
||||
|
||||
// Strings returns an array of currency strings
|
||||
func (c Currencies) Strings() []string {
|
||||
var list []string
|
||||
for _, d := range c {
|
||||
list = append(list, d.String())
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// Contains checks to see if a currency code is contained in the currency list
|
||||
func (c Currencies) Contains(cc Code) bool {
|
||||
for i := range c {
|
||||
if c[i].Item == cc.Item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Join returns a comma serparated string
|
||||
func (c Currencies) Join() string {
|
||||
return common.JoinStrings(c.Strings(), ",")
|
||||
}
|
||||
|
||||
// UnmarshalJSON comforms type to the umarshaler interface
|
||||
func (c *Currencies) UnmarshalJSON(d []byte) error {
|
||||
var configCurrencies string
|
||||
err := common.JSONDecode(d, &configCurrencies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var allTheCurrencies Currencies
|
||||
for _, data := range common.SplitStrings(configCurrencies, ",") {
|
||||
allTheCurrencies = append(allTheCurrencies, NewCode(data))
|
||||
}
|
||||
|
||||
*c = allTheCurrencies
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON conforms type to the marshaler interface
|
||||
func (c Currencies) MarshalJSON() ([]byte, error) {
|
||||
return common.JSONEncode(c.Join())
|
||||
}
|
||||
|
||||
// Match returns if the full list equals the supplied list
|
||||
func (c Currencies) Match(other Currencies) bool {
|
||||
if len(c) != len(other) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, d := range c {
|
||||
var found bool
|
||||
for i := range other {
|
||||
if d == other[i] {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Slice exposes the underlying type
|
||||
func (c Currencies) Slice() []Code {
|
||||
return c
|
||||
}
|
||||
|
||||
// HasData checks to see if Currencies type has actual currencies
|
||||
func (c Currencies) HasData() bool {
|
||||
return len(c) != 0
|
||||
}
|
||||
50
currency/currencies_test.go
Normal file
50
currency/currencies_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
func TestCurrenciesUnmarshalJSON(t *testing.T) {
|
||||
var unmarshalHere Currencies
|
||||
expected := "btc,usd,ltc,bro,things"
|
||||
encoded, err := common.JSONEncode(expected)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Currencies UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
err = common.JSONDecode(encoded, &unmarshalHere)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Currencies UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
err = common.JSONDecode(encoded, &unmarshalHere)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Currencies UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
if unmarshalHere.Join() != expected {
|
||||
t.Errorf("Test Failed - Currencies UnmarshalJSON() error expected %s but received %s",
|
||||
expected, unmarshalHere.Join())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrenciesMarshalJSON(t *testing.T) {
|
||||
quickStruct := struct {
|
||||
C Currencies `json:"amazingCurrencies"`
|
||||
}{
|
||||
C: NewCurrenciesFromStringArray([]string{"btc", "usd", "ltc", "bro", "things"}),
|
||||
}
|
||||
|
||||
encoded, err := common.JSONEncode(quickStruct)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Currencies MarshalJSON() error", err)
|
||||
}
|
||||
|
||||
expected := `{"amazingCurrencies":"btc,usd,ltc,bro,things"}`
|
||||
if string(encoded) != expected {
|
||||
t.Errorf("Test Failed - Currencies MarshalJSON() error expected %s but received %s",
|
||||
expected, string(encoded))
|
||||
}
|
||||
}
|
||||
@@ -1,320 +1,119 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
// GetDefaultExchangeRates returns the currency exchange rates based off the
|
||||
// default fiat values
|
||||
func GetDefaultExchangeRates() (Conversions, error) {
|
||||
return storage.GetDefaultForeignExchangeRates()
|
||||
}
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/coinmarketcap"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
// GetExchangeRates returns the full fiat currency exchange rates base off
|
||||
// configuration parameters supplied to the currency storage
|
||||
func GetExchangeRates() (Conversions, error) {
|
||||
return storage.GetExchangeRates()
|
||||
}
|
||||
|
||||
const (
|
||||
// DefaultBaseCurrency is the base currency used for conversion
|
||||
DefaultBaseCurrency = "USD"
|
||||
// DefaultCurrencies has the default minimum of FIAT values
|
||||
DefaultCurrencies = "USD,AUD,EUR,CNY"
|
||||
// DefaultCryptoCurrencies has the default minimum of crytpocurrency values
|
||||
DefaultCryptoCurrencies = "BTC,LTC,ETH,DOGE,DASH,XRP,XMR"
|
||||
)
|
||||
// UpdateBaseCurrency updates storage base currency
|
||||
func UpdateBaseCurrency(c Code) error {
|
||||
return storage.UpdateBaseCurrency(c)
|
||||
}
|
||||
|
||||
// Manager is the overarching type across this package
|
||||
var (
|
||||
FXRates map[string]float64
|
||||
// GetBaseCurrency returns the storage base currency
|
||||
func GetBaseCurrency() Code {
|
||||
return storage.GetBaseCurrency()
|
||||
}
|
||||
|
||||
FiatCurrencies []string
|
||||
CryptoCurrencies []string
|
||||
// GetDefaultBaseCurrency returns storage default base currency
|
||||
func GetDefaultBaseCurrency() Code {
|
||||
return storage.GetDefaultBaseCurrency()
|
||||
}
|
||||
|
||||
BaseCurrency string
|
||||
FXProviders *forexprovider.ForexProviders
|
||||
// GetCryptocurrencies returns the storage enabled cryptocurrencies
|
||||
func GetCryptocurrencies() Currencies {
|
||||
return storage.GetCryptocurrencies()
|
||||
}
|
||||
|
||||
CryptocurrencyProvider *coinmarketcap.Coinmarketcap
|
||||
TotalCryptocurrencies []Data
|
||||
TotalExchanges []Data
|
||||
)
|
||||
// GetDefaultCryptocurrencies returns a list of default cryptocurrencies
|
||||
func GetDefaultCryptocurrencies() Currencies {
|
||||
return storage.GetDefaultCryptocurrencies()
|
||||
}
|
||||
|
||||
// SetDefaults sets the default currency provider and settings for
|
||||
// currency conversion used outside of the bot setting
|
||||
func SetDefaults() {
|
||||
FXRates = make(map[string]float64)
|
||||
BaseCurrency = DefaultBaseCurrency
|
||||
// GetFiatCurrencies returns the storage enabled fiat currencies
|
||||
func GetFiatCurrencies() Currencies {
|
||||
return storage.GetFiatCurrencies()
|
||||
}
|
||||
|
||||
FXProviders = forexprovider.NewDefaultFXProvider()
|
||||
err := SeedCurrencyData(DefaultCurrencies)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to seed currency data. Err: %s", err)
|
||||
// GetDefaultFiatCurrencies returns a list of default fiat currencies
|
||||
func GetDefaultFiatCurrencies() Currencies {
|
||||
return storage.GetDefaultFiatCurrencies()
|
||||
}
|
||||
|
||||
// UpdateCurrencies updates the local cryptocurrency or fiat currency store
|
||||
func UpdateCurrencies(c Currencies, isCryptocurrency bool) {
|
||||
if isCryptocurrency {
|
||||
storage.UpdateEnabledCryptoCurrencies(c)
|
||||
return
|
||||
}
|
||||
storage.UpdateEnabledFiatCurrencies(c)
|
||||
}
|
||||
|
||||
// SeedCurrencyData returns rates correlated with suported currencies
|
||||
func SeedCurrencyData(currencies string) error {
|
||||
if FXRates == nil {
|
||||
FXRates = make(map[string]float64)
|
||||
}
|
||||
|
||||
if FXProviders == nil {
|
||||
FXProviders = forexprovider.NewDefaultFXProvider()
|
||||
}
|
||||
|
||||
newRates, err := FXProviders.GetCurrencyData(BaseCurrency, currencies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for key, value := range newRates {
|
||||
FXRates[key] = value
|
||||
}
|
||||
|
||||
return nil
|
||||
// ConvertCurrency converts an amount from one currency to another
|
||||
func ConvertCurrency(amount float64, from, to Code) (float64, error) {
|
||||
return storage.ConvertCurrency(amount, from, to)
|
||||
}
|
||||
|
||||
// GetExchangeRates returns the currency exchange rates
|
||||
func GetExchangeRates() map[string]float64 {
|
||||
return FXRates
|
||||
// SeedForeignExchangeData seeds FX data with the currencies supplied
|
||||
func SeedForeignExchangeData(c Currencies) error {
|
||||
return storage.SeedForeignExchangeRatesByCurrencies(c)
|
||||
}
|
||||
|
||||
// IsDefaultCurrency checks if the currency passed in matches the default fiat
|
||||
// currency
|
||||
func IsDefaultCurrency(currency string) bool {
|
||||
defaultCurrencies := common.SplitStrings(DefaultCurrencies, ",")
|
||||
return common.StringDataCompare(defaultCurrencies, common.StringToUpper(currency))
|
||||
// GetTotalMarketCryptocurrencies returns the full market cryptocurrencies
|
||||
func GetTotalMarketCryptocurrencies() ([]Code, error) {
|
||||
return storage.GetTotalMarketCryptocurrencies()
|
||||
}
|
||||
|
||||
// IsDefaultCryptocurrency checks if the currency passed in matches the default
|
||||
// cryptocurrency
|
||||
func IsDefaultCryptocurrency(currency string) bool {
|
||||
cryptoCurrencies := common.SplitStrings(DefaultCryptoCurrencies, ",")
|
||||
return common.StringDataCompare(cryptoCurrencies, common.StringToUpper(currency))
|
||||
// RunStorageUpdater runs a new foreign exchange updater instance
|
||||
func RunStorageUpdater(o BotOverrides, m MainConfiguration, filepath string, v bool) error {
|
||||
return storage.RunUpdater(o, m, filepath, v)
|
||||
}
|
||||
|
||||
// IsFiatCurrency checks if the currency passed is an enabled fiat currency
|
||||
func IsFiatCurrency(currency string) bool {
|
||||
return common.StringDataCompare(FiatCurrencies, common.StringToUpper(currency))
|
||||
}
|
||||
|
||||
// IsCryptocurrency checks if the currency passed is an enabled CRYPTO currency.
|
||||
func IsCryptocurrency(currency string) bool {
|
||||
return common.StringDataCompare(CryptoCurrencies, common.StringToUpper(currency))
|
||||
}
|
||||
|
||||
// IsCryptoPair checks to see if the pair is a crypto pair e.g. BTCLTC
|
||||
func IsCryptoPair(p pair.CurrencyPair) bool {
|
||||
return IsCryptocurrency(p.FirstCurrency.String()) &&
|
||||
IsCryptocurrency(p.SecondCurrency.String())
|
||||
}
|
||||
|
||||
// IsCryptoFiatPair checks to see if the pair is a crypto fiat pair e.g. BTCUSD
|
||||
func IsCryptoFiatPair(p pair.CurrencyPair) bool {
|
||||
return IsCryptocurrency(p.FirstCurrency.String()) && !IsCryptocurrency(p.SecondCurrency.String()) ||
|
||||
!IsCryptocurrency(p.FirstCurrency.String()) && IsCryptocurrency(p.SecondCurrency.String())
|
||||
}
|
||||
|
||||
// IsFiatPair checks to see if the pair is a fiat pair e.g. EURUSD
|
||||
func IsFiatPair(p pair.CurrencyPair) bool {
|
||||
return IsFiatCurrency(p.FirstCurrency.String()) &&
|
||||
IsFiatCurrency(p.SecondCurrency.String())
|
||||
}
|
||||
|
||||
// Update updates the local crypto currency or base currency store
|
||||
func Update(input []string, cryptos bool) {
|
||||
for x := range input {
|
||||
if cryptos {
|
||||
if !common.StringDataCompare(CryptoCurrencies, input[x]) {
|
||||
CryptoCurrencies = append(CryptoCurrencies, common.StringToUpper(input[x]))
|
||||
// CopyPairFormat copies the pair format from a list of pairs once matched
|
||||
func CopyPairFormat(p Pair, pairs []Pair, exact bool) Pair {
|
||||
for x := range pairs {
|
||||
if exact {
|
||||
if p.Equal(pairs[x]) {
|
||||
return pairs[x]
|
||||
}
|
||||
}
|
||||
if p.EqualIncludeReciprocal(pairs[x]) {
|
||||
return pairs[x]
|
||||
}
|
||||
}
|
||||
return Pair{Base: NewCode(""), Quote: NewCode("")}
|
||||
}
|
||||
|
||||
// FormatPairs formats a string array to a list of currency pairs with the
|
||||
// supplied currency pair format
|
||||
func FormatPairs(pairs []string, delimiter, index string) (Pairs, error) {
|
||||
var result Pairs
|
||||
for x := range pairs {
|
||||
if pairs[x] == "" {
|
||||
continue
|
||||
}
|
||||
var p Pair
|
||||
if delimiter != "" {
|
||||
p = NewPairDelimiter(pairs[x], delimiter)
|
||||
} else {
|
||||
if !common.StringDataCompare(FiatCurrencies, input[x]) {
|
||||
FiatCurrencies = append(FiatCurrencies, common.StringToUpper(input[x]))
|
||||
if index != "" {
|
||||
var err error
|
||||
p, err = NewPairFromIndex(pairs[x], index)
|
||||
if err != nil {
|
||||
return Pairs{}, err
|
||||
}
|
||||
} else {
|
||||
p = NewPairFromStrings(pairs[x][0:3], pairs[x][3:])
|
||||
}
|
||||
}
|
||||
result = append(result, p)
|
||||
}
|
||||
}
|
||||
|
||||
func extractBaseCurrency() string {
|
||||
for k := range FXRates {
|
||||
return k[0:3]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ConvertCurrency for example converts $1 USD to the equivalent Japanese Yen
|
||||
// or vice versa.
|
||||
func ConvertCurrency(amount float64, from, to string) (float64, error) {
|
||||
if FXProviders == nil {
|
||||
SetDefaults()
|
||||
}
|
||||
|
||||
from = common.StringToUpper(from)
|
||||
to = common.StringToUpper(to)
|
||||
|
||||
if from == to {
|
||||
return amount, nil
|
||||
}
|
||||
|
||||
if from == "RUR" {
|
||||
from = "RUB"
|
||||
}
|
||||
|
||||
if to == "RUR" {
|
||||
to = "RUB"
|
||||
}
|
||||
|
||||
if len(FXRates) == 0 {
|
||||
SeedCurrencyData(from + "," + to)
|
||||
}
|
||||
|
||||
// Need to extract the base currency to see if we actually got it from the Forex API
|
||||
// Fixer free API sets the base currency to EUR
|
||||
baseCurr := extractBaseCurrency()
|
||||
|
||||
var resultFrom float64
|
||||
var resultTo float64
|
||||
|
||||
// check to see if we're converting from the base currency
|
||||
if to == baseCurr {
|
||||
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 amount / resultFrom, nil
|
||||
}
|
||||
|
||||
// Check to see if we're converting from the base currency
|
||||
if from == baseCurr {
|
||||
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 resultTo * amount, nil
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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 converted * resultTo, nil
|
||||
}
|
||||
|
||||
// Data defines information pertaining to exchange or a cryptocurrency from
|
||||
// coinmarketcap
|
||||
type Data struct {
|
||||
ID int
|
||||
Name string
|
||||
Symbol string `json:",omitempty"`
|
||||
Slug string
|
||||
Active bool
|
||||
LastUpdated time.Time
|
||||
}
|
||||
|
||||
// SeedCryptocurrencyMarketData seeds cryptocurrency market data
|
||||
func SeedCryptocurrencyMarketData(settings coinmarketcap.Settings) error {
|
||||
if !settings.Enabled {
|
||||
return errors.New("not enabled please set in config.json with apikey and account levels")
|
||||
}
|
||||
|
||||
if CryptocurrencyProvider == nil {
|
||||
err := setupCryptoProvider(settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cryptoData, err := CryptocurrencyProvider.GetCryptocurrencyIDMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for x := range cryptoData {
|
||||
var active bool
|
||||
if cryptoData[x].IsActive == 1 {
|
||||
active = true
|
||||
}
|
||||
|
||||
TotalCryptocurrencies = append(TotalCryptocurrencies, Data{
|
||||
ID: cryptoData[x].ID,
|
||||
Name: cryptoData[x].Name,
|
||||
Symbol: cryptoData[x].Symbol,
|
||||
Slug: cryptoData[x].Slug,
|
||||
Active: active,
|
||||
LastUpdated: time.Now(),
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SeedExchangeMarketData seeds exchange market data
|
||||
func SeedExchangeMarketData(settings coinmarketcap.Settings) error {
|
||||
if !settings.Enabled {
|
||||
return errors.New("not enabled please set in config.json with apikey and account levels")
|
||||
}
|
||||
|
||||
if CryptocurrencyProvider == nil {
|
||||
err := setupCryptoProvider(settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
exchangeData, err := CryptocurrencyProvider.GetExchangeMap(0, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, data := range exchangeData {
|
||||
var active bool
|
||||
if data.IsActive == 1 {
|
||||
active = true
|
||||
}
|
||||
|
||||
TotalExchanges = append(TotalExchanges, Data{
|
||||
ID: data.ID,
|
||||
Name: data.Name,
|
||||
Slug: data.Slug,
|
||||
Active: active,
|
||||
LastUpdated: time.Now(),
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupCryptoProvider(settings coinmarketcap.Settings) error {
|
||||
if settings.APIkey == "" ||
|
||||
settings.APIkey == "key" ||
|
||||
settings.AccountPlan == "" ||
|
||||
settings.AccountPlan == "accountPlan" {
|
||||
return errors.New("currencyprovider error api key or plan not set in config.json")
|
||||
}
|
||||
|
||||
CryptocurrencyProvider = new(coinmarketcap.Coinmarketcap)
|
||||
CryptocurrencyProvider.SetDefaults()
|
||||
CryptocurrencyProvider.Setup(settings)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTotalMarketCryptocurrencies returns the total seeded market
|
||||
// cryptocurrencies
|
||||
func GetTotalMarketCryptocurrencies() []Data {
|
||||
return TotalCryptocurrencies
|
||||
}
|
||||
|
||||
// GetTotalMarketExchanges returns the total seeded market exchanges
|
||||
func GetTotalMarketExchanges() []Data {
|
||||
return TotalExchanges
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -2,259 +2,125 @@ package currency
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
)
|
||||
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
FXRates = nil
|
||||
BaseCurrency = "BLAH"
|
||||
FXProviders = nil
|
||||
|
||||
SetDefaults()
|
||||
|
||||
if FXRates == nil {
|
||||
t.Fatal("Expected FXRates to be non-nil")
|
||||
}
|
||||
|
||||
if BaseCurrency != DefaultBaseCurrency {
|
||||
t.Fatal("Expected BaseCurrency to be 'USD'")
|
||||
}
|
||||
|
||||
if FXProviders == nil {
|
||||
t.Fatal("Expected FXRates to be non-nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeedCurrencyData(t *testing.T) {
|
||||
err := SeedCurrencyData("AUD")
|
||||
func TestGetDefaultExchangeRates(t *testing.T) {
|
||||
rates, err := GetDefaultExchangeRates()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
t.Error("Test failed - GetDefaultExchangeRates() err", err)
|
||||
}
|
||||
|
||||
for _, val := range rates {
|
||||
if !val.IsFiat() {
|
||||
t.Errorf("Test failed - GetDefaultExchangeRates() %s is not fiat pair",
|
||||
val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetExchangeRates(t *testing.T) {
|
||||
result := make(map[string]float64)
|
||||
for k, v := range GetExchangeRates() {
|
||||
result[k] = v
|
||||
}
|
||||
backup := FXRates
|
||||
|
||||
FXRates = nil
|
||||
result = GetExchangeRates()
|
||||
if result != nil {
|
||||
t.Fatal("Expected nil map")
|
||||
rates, err := GetExchangeRates()
|
||||
if err != nil {
|
||||
t.Error("Test failed - GetExchangeRates() err", err)
|
||||
}
|
||||
|
||||
FXRates = backup
|
||||
}
|
||||
|
||||
func TestIsDefaultCurrency(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var str1, str2, str3 string = "USD", "usd", "cats123"
|
||||
|
||||
if !IsDefaultCurrency(str1) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsDefaultCurrency: \nCannot match currency, %s.", str1,
|
||||
)
|
||||
}
|
||||
if !IsDefaultCurrency(str2) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsDefaultCurrency: \nCannot match currency, %s.", str2,
|
||||
)
|
||||
}
|
||||
if IsDefaultCurrency(str3) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsDefaultCurrency: \nFunction return is incorrect with, %s.",
|
||||
str3,
|
||||
)
|
||||
for _, val := range rates {
|
||||
if !val.IsFiat() {
|
||||
t.Errorf("Test failed - GetExchangeRates() %s is not fiat pair",
|
||||
val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsDefaultCryptocurrency(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var str1, str2, str3 string = symbol.BTC, symbol.BTC, "dogs123"
|
||||
|
||||
if !IsDefaultCryptocurrency(str1) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsDefaultCryptocurrency: \nCannot match currency, %s.",
|
||||
str1,
|
||||
)
|
||||
func TestUpdateBaseCurrency(t *testing.T) {
|
||||
err := UpdateBaseCurrency(AUD)
|
||||
if err != nil {
|
||||
t.Error("Test failed - UpdateBaseCurrency() err", err)
|
||||
}
|
||||
if !IsDefaultCryptocurrency(str2) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsDefaultCryptocurrency: \nCannot match currency, %s.",
|
||||
str2,
|
||||
)
|
||||
|
||||
err = UpdateBaseCurrency(LTC)
|
||||
if err == nil {
|
||||
t.Error("Test failed - UpdateBaseCurrency() cannot be nil")
|
||||
}
|
||||
if IsDefaultCryptocurrency(str3) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsDefaultCryptocurrency: \nFunction return is incorrect with, %s.",
|
||||
str3,
|
||||
)
|
||||
|
||||
if GetBaseCurrency() != AUD {
|
||||
t.Errorf("Test failed - GetBaseCurrency() expected %s but recieved %s",
|
||||
AUD, GetBaseCurrency())
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsFiatCurrency(t *testing.T) {
|
||||
if IsFiatCurrency("") {
|
||||
t.Error("Test failed. TestIsFiatCurrency returned true on an empty string")
|
||||
}
|
||||
|
||||
FiatCurrencies = []string{"USD", "AUD"}
|
||||
var str1, str2, str3 string = symbol.BTC, "USD", "birds123"
|
||||
|
||||
if IsFiatCurrency(str1) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsFiatCurrency: \nCannot match currency, %s.", str1,
|
||||
)
|
||||
}
|
||||
if !IsFiatCurrency(str2) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsFiatCurrency: \nCannot match currency, %s.", str2,
|
||||
)
|
||||
}
|
||||
if IsFiatCurrency(str3) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsFiatCurrency: \nCannot match currency, %s.", str3,
|
||||
)
|
||||
func TestGetDefaultBaseCurrency(t *testing.T) {
|
||||
if GetDefaultBaseCurrency() != USD {
|
||||
t.Errorf("Test failed - GetDefaultBaseCurrency() expected %s but recieved %s",
|
||||
USD, GetDefaultBaseCurrency())
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCryptocurrency(t *testing.T) {
|
||||
if IsCryptocurrency("") {
|
||||
t.Error("Test failed. TestIsCryptocurrency returned true on an empty string")
|
||||
}
|
||||
|
||||
CryptoCurrencies = []string{symbol.BTC, symbol.LTC, symbol.DASH}
|
||||
var str1, str2, str3 string = "USD", symbol.BTC, "pterodactyl123"
|
||||
|
||||
if IsCryptocurrency(str1) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsFiatCurrency: \nCannot match currency, %s.", str1,
|
||||
)
|
||||
}
|
||||
if !IsCryptocurrency(str2) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsFiatCurrency: \nCannot match currency, %s.", str2,
|
||||
)
|
||||
}
|
||||
if IsCryptocurrency(str3) {
|
||||
t.Errorf(
|
||||
"Test Failed. TestIsFiatCurrency: \nCannot match currency, %s.", str3,
|
||||
)
|
||||
func TestGetDefaulCryptoCurrencies(t *testing.T) {
|
||||
expected := Currencies{BTC, LTC, ETH, DOGE, DASH, XRP, XMR}
|
||||
if !GetDefaultCryptocurrencies().Match(expected) {
|
||||
t.Errorf("Test failed - GetDefaultCryptocurrencies() expected %s but recieved %s",
|
||||
expected, GetDefaultCryptocurrencies())
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCryptoPair(t *testing.T) {
|
||||
if IsCryptocurrency("") {
|
||||
t.Error("Test failed. TestIsCryptocurrency returned true on an empty string")
|
||||
}
|
||||
|
||||
CryptoCurrencies = []string{symbol.BTC, symbol.LTC, symbol.DASH}
|
||||
FiatCurrencies = []string{"USD"}
|
||||
|
||||
if !IsCryptoPair(pair.NewCurrencyPair(symbol.BTC, symbol.LTC)) {
|
||||
t.Error("Test Failed. TestIsCryptoPair. Expected true result")
|
||||
}
|
||||
|
||||
if IsCryptoPair(pair.NewCurrencyPair(symbol.BTC, "USD")) {
|
||||
t.Error("Test Failed. TestIsCryptoPair. Expected false result")
|
||||
func TestGetDefaultFiatCurrencies(t *testing.T) {
|
||||
expected := Currencies{USD, AUD, EUR, CNY}
|
||||
if !GetDefaultFiatCurrencies().Match(expected) {
|
||||
t.Errorf("Test failed - GetDefaultFiatCurrencies() expected %s but recieved %s",
|
||||
expected, GetDefaultFiatCurrencies())
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCryptoFiatPair(t *testing.T) {
|
||||
if IsCryptocurrency("") {
|
||||
t.Error("Test failed. TestIsCryptocurrency returned true on an empty string")
|
||||
func TestUpdateCurrencies(t *testing.T) {
|
||||
fiat := Currencies{HKN, JPY}
|
||||
UpdateCurrencies(fiat, false)
|
||||
rFiat := GetFiatCurrencies()
|
||||
if !rFiat.Contains(HKN) || !rFiat.Contains(JPY) {
|
||||
t.Error("Test failed - UpdateCurrencies() currencies did not update")
|
||||
}
|
||||
|
||||
CryptoCurrencies = []string{symbol.BTC, symbol.LTC, symbol.DASH}
|
||||
FiatCurrencies = []string{"USD"}
|
||||
|
||||
if !IsCryptoFiatPair(pair.NewCurrencyPair(symbol.BTC, "USD")) {
|
||||
t.Error("Test Failed. TestIsCryptoPair. Expected true result")
|
||||
}
|
||||
|
||||
if IsCryptoFiatPair(pair.NewCurrencyPair(symbol.BTC, symbol.LTC)) {
|
||||
t.Error("Test Failed. TestIsCryptoPair. Expected false result")
|
||||
crypto := Currencies{ZAR, ZCAD, B2}
|
||||
UpdateCurrencies(crypto, true)
|
||||
rCrypto := GetCryptocurrencies()
|
||||
if !rCrypto.Contains(ZAR) || !rCrypto.Contains(ZCAD) || !rCrypto.Contains(B2) {
|
||||
t.Error("Test failed - UpdateCurrencies() currencies did not update")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsFiatPair(t *testing.T) {
|
||||
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(symbol.BTC, "AUD")) {
|
||||
t.Error("Test Failed. TestIsFiatPair. Expected false result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
CryptoCurrencies = []string{symbol.BTC, symbol.LTC, symbol.DASH}
|
||||
FiatCurrencies = []string{"USD", "AUD"}
|
||||
|
||||
Update([]string{"ETH"}, true)
|
||||
Update([]string{"JPY"}, false)
|
||||
|
||||
if !IsCryptocurrency("ETH") {
|
||||
t.Error(
|
||||
"Test Failed. TestUpdate: \nCannot match currency: ETH",
|
||||
)
|
||||
}
|
||||
|
||||
if !IsFiatCurrency("JPY") {
|
||||
t.Errorf(
|
||||
"Test Failed. TestUpdate: \nCannot match currency: JPY",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractBaseCurrency(t *testing.T) {
|
||||
backup := FXRates
|
||||
FXRates = nil
|
||||
FXRates = make(map[string]float64)
|
||||
|
||||
if extractBaseCurrency() != "" {
|
||||
t.Fatalf("Test failed. Expected '' as base currency")
|
||||
}
|
||||
|
||||
FXRates["USDAUD"] = 120
|
||||
|
||||
if extractBaseCurrency() != "USD" {
|
||||
t.Fatalf("Test failed. Expected 'USD' as base currency")
|
||||
}
|
||||
FXRates = backup
|
||||
}
|
||||
func TestConvertCurrency(t *testing.T) {
|
||||
_, err := ConvertCurrency(100, "AUD", "USD")
|
||||
_, err := ConvertCurrency(100, AUD, USD)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = ConvertCurrency(100, "USD", "AUD")
|
||||
r, err := ConvertCurrency(100, AUD, AUD)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = ConvertCurrency(100, "CNY", "AUD")
|
||||
if r != 100 {
|
||||
t.Errorf("Test Failed - ConvertCurrency error, incorrect rate return %2.f but received %2.f",
|
||||
100.00, r)
|
||||
}
|
||||
|
||||
_, err = ConvertCurrency(100, USD, AUD)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = ConvertCurrency(100, "meow", "USD")
|
||||
_, err = ConvertCurrency(100, CNY, AUD)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = ConvertCurrency(100, LTC, USD)
|
||||
if err == nil {
|
||||
t.Fatal("Expected err on non-existent currency")
|
||||
}
|
||||
|
||||
_, err = ConvertCurrency(100, "USD", "meow")
|
||||
_, err = ConvertCurrency(100, USD, LTC)
|
||||
if err == nil {
|
||||
t.Fatal("Expected err on non-existent currency")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
62
currency/currency_types.go
Normal file
62
currency/currency_types.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency/coinmarketcap"
|
||||
)
|
||||
|
||||
// MainConfiguration is the main configuration from the config.json file
|
||||
type MainConfiguration struct {
|
||||
ForexProviders []FXSettings
|
||||
CryptocurrencyProvider coinmarketcap.Settings
|
||||
Cryptocurrencies Currencies
|
||||
CurrencyPairFormat interface{}
|
||||
FiatDisplayCurrency Code
|
||||
CurrencyDelay time.Duration
|
||||
FxRateDelay time.Duration
|
||||
}
|
||||
|
||||
// BotOverrides defines a bot overriding factor for quick running currency
|
||||
// subsystems
|
||||
type BotOverrides struct {
|
||||
Coinmarketcap bool
|
||||
FxCurrencyConverter bool
|
||||
FxCurrencyLayer bool
|
||||
FxFixer bool
|
||||
FxOpenExchangeRates bool
|
||||
}
|
||||
|
||||
// CoinmarketcapSettings refers to settings
|
||||
type CoinmarketcapSettings coinmarketcap.Settings
|
||||
|
||||
// SystemsSettings defines incoming system settings
|
||||
type SystemsSettings struct {
|
||||
Coinmarketcap coinmarketcap.Settings
|
||||
Currencyconverter FXSettings
|
||||
Currencylayer FXSettings
|
||||
Fixer FXSettings
|
||||
Openexchangerates FXSettings
|
||||
}
|
||||
|
||||
// FXSettings defines foreign exchange requester settings
|
||||
type FXSettings struct {
|
||||
Name string `json:"name"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Verbose bool `json:"verbose"`
|
||||
RESTPollingDelay time.Duration `json:"restPollingDelay"`
|
||||
APIKey string `json:"apiKey"`
|
||||
APIKeyLvl int `json:"apiKeyLvl"`
|
||||
PrimaryProvider bool `json:"primaryProvider"`
|
||||
}
|
||||
|
||||
// File defines a full currency file generated by the currency storage
|
||||
// analysis system
|
||||
type File struct {
|
||||
LastMainUpdate time.Time `json:"lastMainUpdate"`
|
||||
Cryptocurrency []Item `json:"cryptocurrencies"`
|
||||
FiatCurrency []Item `json:"fiatCurrencies"`
|
||||
UnsetCurrency []Item `json:"unsetCurrencies"`
|
||||
Contracts []Item `json:"contracts"`
|
||||
Token []Item `json:"tokens"`
|
||||
}
|
||||
@@ -4,6 +4,9 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// DefaultTimeOut is the default timeout for foreign exchange providers
|
||||
const DefaultTimeOut = time.Second * 15
|
||||
|
||||
// Settings enforces standard variables across the provider packages
|
||||
type Settings struct {
|
||||
Name string `json:"name"`
|
||||
|
||||
@@ -3,44 +3,153 @@ package base
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
// IFXProviders contains an array of foreign exchange interfaces
|
||||
type IFXProviders []IFXProvider
|
||||
|
||||
// IFXProvider enforces standard functions for all foreign exchange providers
|
||||
// supported in GoCryptoTrader
|
||||
type IFXProvider interface {
|
||||
Setup(config Settings)
|
||||
Setup(config Settings) error
|
||||
GetRates(baseCurrency, symbols string) (map[string]float64, error)
|
||||
GetName() string
|
||||
IsEnabled() bool
|
||||
IsPrimaryProvider() bool
|
||||
GetSupportedCurrencies() ([]string, error)
|
||||
}
|
||||
|
||||
// FXHandler defines a full suite of FX data providers with failure backup with
|
||||
// unsupported currency shunt procedure
|
||||
type FXHandler struct {
|
||||
Primary Provider
|
||||
Support []Provider
|
||||
mtx sync.Mutex
|
||||
}
|
||||
|
||||
// Provider defines a singular foreign exchange provider with its supported
|
||||
// currencies to cross reference request currencies and if not supported shunt
|
||||
// request traffic to and from other providers so that we can maintain full
|
||||
// currency list integration
|
||||
type Provider struct {
|
||||
Provider IFXProvider
|
||||
SupportedCurrencies []string
|
||||
}
|
||||
|
||||
// GetNewRate access rates by predetermined logic based on how a provider
|
||||
// handles requests
|
||||
func (p *Provider) GetNewRate(base string, currencies []string) (map[string]float64, error) {
|
||||
if !p.Provider.IsEnabled() {
|
||||
return nil, fmt.Errorf("provider %s is not enabled",
|
||||
p.Provider.GetName())
|
||||
}
|
||||
|
||||
switch p.Provider.GetName() {
|
||||
case "ExchangeRates":
|
||||
return p.Provider.GetRates(base, "") // Zero value to get all rates
|
||||
|
||||
default:
|
||||
return p.Provider.GetRates(base, common.JoinStrings(currencies, ","))
|
||||
}
|
||||
}
|
||||
|
||||
// CheckCurrencies cross references supplied currencies with exchange supported
|
||||
// currencies, if there are any currencies not supported it returns a list
|
||||
// to pass on to the next provider
|
||||
func (p Provider) CheckCurrencies(currencies []string) []string {
|
||||
var spillOver []string
|
||||
for _, c := range currencies {
|
||||
if !common.StringDataCompareUpper(p.SupportedCurrencies, c) {
|
||||
spillOver = append(spillOver, c)
|
||||
}
|
||||
}
|
||||
return spillOver
|
||||
}
|
||||
|
||||
// GetCurrencyData returns currency data from enabled FX providers
|
||||
func (fxp IFXProviders) GetCurrencyData(baseCurrency, symbols string) (map[string]float64, error) {
|
||||
for x := range fxp {
|
||||
if fxp[x].IsPrimaryProvider() && fxp[x].IsEnabled() {
|
||||
rates, err := fxp[x].GetRates(baseCurrency, symbols)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
for y := range fxp {
|
||||
if !fxp[y].IsPrimaryProvider() && fxp[x].IsEnabled() {
|
||||
rates, err = fxp[y].GetRates(baseCurrency, symbols)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
continue
|
||||
}
|
||||
return rates, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("forex provider %s unable to acquire rates data", fxp[x].GetName())
|
||||
}
|
||||
return rates, nil
|
||||
}
|
||||
func (f *FXHandler) GetCurrencyData(baseCurrency string, currencies []string) (map[string]float64, error) {
|
||||
var fullRange = currencies
|
||||
|
||||
if !common.StringDataCompareUpper(currencies, baseCurrency) {
|
||||
fullRange = append(fullRange, baseCurrency)
|
||||
}
|
||||
return nil, errors.New("no forex providers enabled")
|
||||
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
|
||||
if f.Primary.Provider == nil {
|
||||
return nil, errors.New("primary foreign exchange provider details not set")
|
||||
}
|
||||
|
||||
shunt := f.Primary.CheckCurrencies(fullRange)
|
||||
rates, err := f.Primary.GetNewRate(baseCurrency, currencies)
|
||||
if err != nil {
|
||||
return f.backupGetRate(baseCurrency, currencies)
|
||||
}
|
||||
|
||||
if len(shunt) != 0 {
|
||||
rateNew, err := f.backupGetRate(baseCurrency, shunt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update rate map for currencies %v %v",
|
||||
shunt,
|
||||
err)
|
||||
}
|
||||
|
||||
for key, val := range rateNew {
|
||||
rates[key] = val
|
||||
}
|
||||
|
||||
return rates, nil
|
||||
}
|
||||
|
||||
return rates, nil
|
||||
}
|
||||
|
||||
// backupGetRate uses the currencies that are supported and falls through, and
|
||||
// errors when unsupported currency found
|
||||
func (f *FXHandler) backupGetRate(base string, currencies []string) (map[string]float64, error) {
|
||||
if f.Support == nil {
|
||||
return nil, errors.New("no supporting foreign exchange providers set")
|
||||
}
|
||||
|
||||
var shunt []string
|
||||
rate := make(map[string]float64)
|
||||
|
||||
for i := range f.Support {
|
||||
if len(shunt) != 0 {
|
||||
shunt = f.Support[i].CheckCurrencies(shunt)
|
||||
newRate, err := f.Support[i].GetNewRate(base, shunt)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for k, v := range newRate {
|
||||
rate[k] = v
|
||||
}
|
||||
|
||||
if len(shunt) != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
return rate, nil
|
||||
}
|
||||
|
||||
shunt = f.Support[i].CheckCurrencies(currencies)
|
||||
newRate, err := f.Support[i].GetNewRate(base, currencies)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for k, v := range newRate {
|
||||
rate[k] = v
|
||||
}
|
||||
|
||||
if len(shunt) != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
return rate, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("currencies %s not supported", shunt)
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
package base
|
||||
@@ -3,10 +3,13 @@ package currencyconverter
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
@@ -22,15 +25,19 @@ const (
|
||||
APIEndpointUsage = "usage"
|
||||
|
||||
defaultAPIKey = "Key"
|
||||
|
||||
authRate = 0
|
||||
unAuthRate = 0
|
||||
)
|
||||
|
||||
// CurrencyConverter stores the struct for the CurrencyConverter API
|
||||
type CurrencyConverter struct {
|
||||
base.Base
|
||||
Requester *request.Requester
|
||||
}
|
||||
|
||||
// Setup sets appropriate values for CurrencyLayer
|
||||
func (c *CurrencyConverter) Setup(config base.Settings) {
|
||||
func (c *CurrencyConverter) Setup(config base.Settings) error {
|
||||
c.Name = config.Name
|
||||
c.APIKey = config.APIKey
|
||||
c.APIKeyLvl = config.APIKeyLvl
|
||||
@@ -38,6 +45,11 @@ func (c *CurrencyConverter) Setup(config base.Settings) {
|
||||
c.RESTPollingDelay = config.RESTPollingDelay
|
||||
c.Verbose = config.Verbose
|
||||
c.PrimaryProvider = config.PrimaryProvider
|
||||
c.Requester = request.New(c.Name,
|
||||
request.NewRateLimit(time.Second*10, authRate),
|
||||
request.NewRateLimit(time.Second*10, unAuthRate),
|
||||
common.NewHTTPClientWithTimeout(base.DefaultTimeOut))
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRates is a wrapper function to return rates
|
||||
@@ -128,8 +140,8 @@ func (c *CurrencyConverter) Convert(from, to string) (map[string]float64, error)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetCurrencies returns a list of the supported currencies
|
||||
func (c *CurrencyConverter) GetCurrencies() (map[string]CurrencyItem, error) {
|
||||
// GetSupportedCurrencies returns a list of the supported currencies
|
||||
func (c *CurrencyConverter) GetSupportedCurrencies() ([]string, error) {
|
||||
var result Currencies
|
||||
|
||||
err := c.SendHTTPRequest(APIEndpointCurrencies, url.Values{}, &result)
|
||||
@@ -137,7 +149,12 @@ func (c *CurrencyConverter) GetCurrencies() (map[string]CurrencyItem, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result.Results, nil
|
||||
var currencies []string
|
||||
for key := range result.Results {
|
||||
currencies = append(currencies, key)
|
||||
}
|
||||
|
||||
return currencies, nil
|
||||
}
|
||||
|
||||
// GetCountries returns a list of the supported countries and
|
||||
@@ -157,16 +174,23 @@ func (c *CurrencyConverter) GetCountries() (map[string]CountryItem, error) {
|
||||
// upgrades request to SSL.
|
||||
func (c *CurrencyConverter) SendHTTPRequest(endPoint string, values url.Values, result interface{}) error {
|
||||
var path string
|
||||
|
||||
var auth bool
|
||||
if c.APIKey == "" || c.APIKey == defaultAPIKey {
|
||||
path = fmt.Sprintf("%s%s/%s?", APIEndpointFreeURL, APIEndpointVersion, endPoint)
|
||||
auth = true
|
||||
} else {
|
||||
path = fmt.Sprintf("%s%s%s?", APIEndpointURL, APIEndpointVersion, endPoint)
|
||||
values.Set("apiKey", c.APIKey)
|
||||
}
|
||||
path += values.Encode()
|
||||
|
||||
err := common.SendHTTPGetRequest(path, true, c.Verbose, &result)
|
||||
err := c.Requester.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
&result,
|
||||
auth,
|
||||
c.Verbose)
|
||||
if err != nil {
|
||||
return fmt.Errorf("currency converter API SendHTTPRequest error %s with path %s",
|
||||
err,
|
||||
|
||||
@@ -80,12 +80,12 @@ func TestConvert(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCurrencies(t *testing.T) {
|
||||
func TestGetSupportedCurrencies(t *testing.T) {
|
||||
if !IsAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
_, err := c.GetCurrencies()
|
||||
_, err := c.GetSupportedCurrencies()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -14,11 +14,15 @@ package currencylayer
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
// const declarations consist of endpoints and APIKey privileges
|
||||
@@ -36,6 +40,9 @@ const (
|
||||
APIEndpointConversion = "convert"
|
||||
APIEndpointTimeframe = "timeframe"
|
||||
APIEndpointChange = "change"
|
||||
|
||||
authRate = 0
|
||||
unAuthRate = 0
|
||||
)
|
||||
|
||||
// CurrencyLayer is a foreign exchange rate provider at
|
||||
@@ -43,10 +50,17 @@ const (
|
||||
// account. Has automatic upgrade to a SSL connection.
|
||||
type CurrencyLayer struct {
|
||||
base.Base
|
||||
Requester *request.Requester
|
||||
}
|
||||
|
||||
// Setup sets appropriate values for CurrencyLayer
|
||||
func (c *CurrencyLayer) Setup(config base.Settings) {
|
||||
func (c *CurrencyLayer) Setup(config base.Settings) error {
|
||||
if config.APIKeyLvl < 0 || config.APIKeyLvl > 3 {
|
||||
log.Errorf("apikey incorrectly set in config.json for %s, please set appropriate account levels",
|
||||
config.Name)
|
||||
return errors.New("apikey set failure")
|
||||
}
|
||||
|
||||
c.Name = config.Name
|
||||
c.APIKey = config.APIKey
|
||||
c.APIKeyLvl = config.APIKeyLvl
|
||||
@@ -54,6 +68,12 @@ func (c *CurrencyLayer) Setup(config base.Settings) {
|
||||
c.RESTPollingDelay = config.RESTPollingDelay
|
||||
c.Verbose = config.Verbose
|
||||
c.PrimaryProvider = config.PrimaryProvider
|
||||
c.Requester = request.New(c.Name,
|
||||
request.NewRateLimit(time.Second*10, authRate),
|
||||
request.NewRateLimit(time.Second*10, unAuthRate),
|
||||
common.NewHTTPClientWithTimeout(base.DefaultTimeOut))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRates is a wrapper function to return rates for GoCryptoTrader
|
||||
@@ -62,7 +82,7 @@ func (c *CurrencyLayer) GetRates(baseCurrency, symbols string) (map[string]float
|
||||
}
|
||||
|
||||
// GetSupportedCurrencies returns supported currencies
|
||||
func (c *CurrencyLayer) GetSupportedCurrencies() (map[string]string, error) {
|
||||
func (c *CurrencyLayer) GetSupportedCurrencies() ([]string, error) {
|
||||
var resp SupportedCurrencies
|
||||
|
||||
if err := c.SendHTTPRequest(APIEndpointList, url.Values{}, &resp); err != nil {
|
||||
@@ -72,7 +92,13 @@ func (c *CurrencyLayer) GetSupportedCurrencies() (map[string]string, error) {
|
||||
if !resp.Success {
|
||||
return nil, errors.New(resp.Error.Info)
|
||||
}
|
||||
return resp.Currencies, nil
|
||||
|
||||
var currencies []string
|
||||
for key := range resp.Currencies {
|
||||
currencies = append(currencies, key)
|
||||
}
|
||||
|
||||
return currencies, nil
|
||||
}
|
||||
|
||||
// GetliveData returns live quotes for foreign exchange currencies
|
||||
@@ -198,12 +224,20 @@ func (c *CurrencyLayer) SendHTTPRequest(endPoint string, values url.Values, resu
|
||||
var path string
|
||||
values.Set("access_key", c.APIKey)
|
||||
|
||||
var auth bool
|
||||
if c.APIKeyLvl == AccountFree {
|
||||
path = fmt.Sprintf("%s%s%s", APIEndpointURL, endPoint, "?")
|
||||
} else {
|
||||
auth = true
|
||||
path = fmt.Sprintf("%s%s%s", APIEndpointURLSSL, endPoint, "?")
|
||||
}
|
||||
path += values.Encode()
|
||||
|
||||
return common.SendHTTPGetRequest(path, true, c.Verbose, result)
|
||||
return c.Requester.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
&result,
|
||||
auth,
|
||||
c.Verbose)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package currencylayer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
)
|
||||
|
||||
var c CurrencyLayer
|
||||
@@ -10,54 +12,126 @@ var c CurrencyLayer
|
||||
// minimize your API calls using this test.
|
||||
const (
|
||||
APIkey = ""
|
||||
Apilevel = 3
|
||||
Apilevel = 0
|
||||
)
|
||||
|
||||
var isSet bool
|
||||
|
||||
func setup() error {
|
||||
if !isSet {
|
||||
defaultCfg := base.Settings{
|
||||
Name: "CurrencyLayer",
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
if APIkey != "" {
|
||||
defaultCfg.APIKey = APIkey
|
||||
}
|
||||
|
||||
if Apilevel > -2 && Apilevel < 4 {
|
||||
defaultCfg.APIKeyLvl = Apilevel
|
||||
}
|
||||
|
||||
err := c.Setup(defaultCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
isSet = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func areAPIKeysSet() bool {
|
||||
return APIkey != "" && Apilevel != -1
|
||||
}
|
||||
|
||||
func TestGetRates(t *testing.T) {
|
||||
_, err := c.GetRates("USD", "AUD")
|
||||
if err == nil {
|
||||
err := setup()
|
||||
if err != nil {
|
||||
t.Skip("Test Failed - CurrencyLayer GetRates error", err)
|
||||
}
|
||||
_, err = c.GetRates("USD", "AUD")
|
||||
if areAPIKeysSet() && err != nil {
|
||||
t.Error("test error - currencylayer GetRates() error", err)
|
||||
} else if !areAPIKeysSet() && err == nil {
|
||||
t.Error("test error - currencylayer GetRates() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSupportedCurrencies(t *testing.T) {
|
||||
_, err := c.GetSupportedCurrencies()
|
||||
if err == nil {
|
||||
err := setup()
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - CurrencyLayer GetSupportedCurrencies error", err)
|
||||
}
|
||||
_, err = c.GetSupportedCurrencies()
|
||||
if areAPIKeysSet() && err != nil {
|
||||
t.Error("test error - currencylayer GetSupportedCurrencies() error", err)
|
||||
} else if !areAPIKeysSet() && err == nil {
|
||||
t.Error("test error - currencylayer GetSupportedCurrencies() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetliveData(t *testing.T) {
|
||||
_, err := c.GetliveData("AUD", "USD")
|
||||
if err == nil {
|
||||
err := setup()
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - CurrencyLayer GetliveData error", err)
|
||||
}
|
||||
_, err = c.GetliveData("AUD", "USD")
|
||||
if areAPIKeysSet() && err != nil {
|
||||
t.Error("test error - currencylayer GetliveData() error", err)
|
||||
} else if !areAPIKeysSet() && err == nil {
|
||||
t.Error("test error - currencylayer GetliveData() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetHistoricalData(t *testing.T) {
|
||||
_, err := c.GetHistoricalData("2016-12-15", []string{"AUD"}, "USD")
|
||||
if err == nil {
|
||||
err := setup()
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - CurrencyLayer GetHistoricalData error", err)
|
||||
}
|
||||
_, err = c.GetHistoricalData("2016-12-15", []string{"AUD"}, "USD")
|
||||
if areAPIKeysSet() && err != nil {
|
||||
t.Error("test error - currencylayer GetHistoricalData() error", err)
|
||||
} else if !areAPIKeysSet() && err == nil {
|
||||
t.Error("test error - currencylayer GetHistoricalData() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
_, err := c.Convert("USD", "AUD", "", 1)
|
||||
if err == nil {
|
||||
t.Error("test error - currencylayer Convert() error")
|
||||
err := setup()
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - CurrencyLayer Convert error", err)
|
||||
}
|
||||
_, err = c.Convert("USD", "AUD", "", 1)
|
||||
if areAPIKeysSet() && err != nil && c.APIKeyLvl >= AccountBasic {
|
||||
t.Error("test error - currencylayer Convert() error", err)
|
||||
} else if !areAPIKeysSet() && err == nil {
|
||||
t.Error("test error - currencylayer Convert() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryTimeFrame(t *testing.T) {
|
||||
_, err := c.QueryTimeFrame("2010-12-0", "2010-12-5", "USD", []string{"AUD"})
|
||||
if err == nil {
|
||||
t.Error("test error - currencylayer QueryTimeFrame() error")
|
||||
err := setup()
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - CurrencyLayer QueryTimeFrame error", err)
|
||||
}
|
||||
_, err = c.QueryTimeFrame("2010-12-0", "2010-12-5", "USD", []string{"AUD"})
|
||||
if areAPIKeysSet() && err != nil && c.APIKeyLvl >= AccountPro {
|
||||
t.Error("test error - currencylayer QueryTimeFrame() error", err)
|
||||
} else if !areAPIKeysSet() && err == nil {
|
||||
t.Error("test error - currencylayer QueryTimeFrame() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryCurrencyChange(t *testing.T) {
|
||||
_, err := c.QueryCurrencyChange("2010-12-0", "2010-12-5", "USD", []string{"AUD"})
|
||||
if err == nil {
|
||||
t.Error("test error - currencylayer QueryCurrencyChange() error")
|
||||
err := setup()
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - CurrencyLayer QueryCurrencyChange() error", err)
|
||||
}
|
||||
_, err = c.QueryCurrencyChange("2010-12-0", "2010-12-5", "USD", []string{"AUD"})
|
||||
if areAPIKeysSet() && err != nil && c.APIKeyLvl == AccountEnterprise {
|
||||
t.Error("test error - currencylayer QueryCurrencyChange() error", err)
|
||||
} else if !areAPIKeysSet() && err == nil {
|
||||
t.Error("test error - currencylayer QueryCurrencyChange() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package currencylayer
|
||||
|
||||
// Error Defines the response error if an error occurred
|
||||
type Error struct {
|
||||
Code int `json:"code"`
|
||||
Info string `json:"info"`
|
||||
}
|
||||
|
||||
// LiveRates is a response type holding rates priced now.
|
||||
type LiveRates struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Success bool `json:"success"`
|
||||
Error Error `json:"error"`
|
||||
Terms string `json:"terms"`
|
||||
Privacy string `json:"privacy"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
@@ -16,11 +19,8 @@ type LiveRates struct {
|
||||
|
||||
// SupportedCurrencies holds supported currency information
|
||||
type SupportedCurrencies struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Success bool `json:"success"`
|
||||
Error Error `json:"error"`
|
||||
Terms string `json:"terms"`
|
||||
Privacy string `json:"privacy"`
|
||||
Currencies map[string]string `json:"currencies"`
|
||||
@@ -28,11 +28,8 @@ type SupportedCurrencies struct {
|
||||
|
||||
// HistoricalRates is a response type holding rates priced from the past.
|
||||
type HistoricalRates struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Success bool `json:"success"`
|
||||
Error Error `json:"error"`
|
||||
Terms string `json:"terms"`
|
||||
Privacy string `json:"privacy"`
|
||||
Historical bool `json:"historical"`
|
||||
@@ -44,11 +41,8 @@ type HistoricalRates struct {
|
||||
|
||||
// ConversionRate is a response type holding a converted rate.
|
||||
type ConversionRate struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Success bool `json:"success"`
|
||||
Error Error `json:"error"`
|
||||
Privacy string `json:"privacy"`
|
||||
Terms string `json:"terms"`
|
||||
Query struct {
|
||||
@@ -67,11 +61,8 @@ type ConversionRate struct {
|
||||
|
||||
// TimeFrame is a response type holding exchange rates for a time period
|
||||
type TimeFrame struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Success bool `json:"success"`
|
||||
Error Error `json:"error"`
|
||||
Terms string `json:"terms"`
|
||||
Privacy string `json:"privacy"`
|
||||
Timeframe bool `json:"timeframe"`
|
||||
@@ -83,11 +74,8 @@ type TimeFrame struct {
|
||||
|
||||
// ChangeRate is the response type that holds rate change data.
|
||||
type ChangeRate struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Success bool `json:"success"`
|
||||
Error Error `json:"error"`
|
||||
Terms string `json:"terms"`
|
||||
Privacy string `json:"privacy"`
|
||||
Change bool `json:"change"`
|
||||
|
||||
@@ -3,11 +3,14 @@ package exchangerates
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
@@ -15,23 +18,32 @@ const (
|
||||
exchangeRatesAPI = "https://api.exchangeratesapi.io"
|
||||
exchangeRatesLatest = "latest"
|
||||
exchangeRatesHistory = "history"
|
||||
exchangeRatesSupportedCurrencies = "USD,ISK,CAD,MXN,CHF,AUD,CNY,GBP,SEK,NOK,TRY,IDR,ZAR," +
|
||||
"HRK,EUR,HKD,ILS,NZD,MYR,JPY,CZK,JPY,CZK,SGD,RUB,RON,HUF,BGN,INR,KRW," +
|
||||
"DKK,THB,PHP,PLN,BRL"
|
||||
exchangeRatesSupportedCurrencies = "EUR,CHF,USD,BRL,ISK,PHP,KRW,BGN,MXN," +
|
||||
"RON,CAD,SGD,NZD,THB,HKD,JPY,NOK,HRK,ILS,GBP,DKK,HUF,MYR,RUB,TRY,IDR," +
|
||||
"ZAR,INR,AUD,CZK,SEK,CNY,PLN"
|
||||
|
||||
authRate = 0
|
||||
unAuthRate = 0
|
||||
)
|
||||
|
||||
// ExchangeRates stores the struct for the ExchangeRatesAPI API
|
||||
type ExchangeRates struct {
|
||||
base.Base
|
||||
Requester *request.Requester
|
||||
}
|
||||
|
||||
// Setup sets appropriate values for CurrencyLayer
|
||||
func (e *ExchangeRates) Setup(config base.Settings) {
|
||||
func (e *ExchangeRates) Setup(config base.Settings) error {
|
||||
e.Name = config.Name
|
||||
e.Enabled = config.Enabled
|
||||
e.RESTPollingDelay = config.RESTPollingDelay
|
||||
e.Verbose = config.Verbose
|
||||
e.PrimaryProvider = config.PrimaryProvider
|
||||
e.Requester = request.New(e.Name,
|
||||
request.NewRateLimit(time.Second*10, authRate),
|
||||
request.NewRateLimit(time.Second*10, unAuthRate),
|
||||
common.NewHTTPClientWithTimeout(base.DefaultTimeOut))
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanCurrencies(baseCurrency, symbols string) string {
|
||||
@@ -150,10 +162,21 @@ func (e *ExchangeRates) GetRates(baseCurrency, symbols string) (map[string]float
|
||||
return standardisedRates, nil
|
||||
}
|
||||
|
||||
// GetSupportedCurrencies returns the supported currency list
|
||||
func (e *ExchangeRates) GetSupportedCurrencies() ([]string, error) {
|
||||
return common.SplitStrings(exchangeRatesSupportedCurrencies, ","), nil
|
||||
}
|
||||
|
||||
// SendHTTPRequest sends a HTTPS request to the desired endpoint and returns the result
|
||||
func (e *ExchangeRates) SendHTTPRequest(endPoint string, values url.Values, result interface{}) error {
|
||||
path := common.EncodeURLValues(exchangeRatesAPI+"/"+endPoint, values)
|
||||
err := common.SendHTTPGetRequest(path, true, e.Verbose, &result)
|
||||
err := e.Requester.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
&result,
|
||||
false,
|
||||
e.Verbose)
|
||||
if err != nil {
|
||||
return fmt.Errorf("exchangeRatesAPI SendHTTPRequest error %s with path %s",
|
||||
err,
|
||||
|
||||
@@ -2,12 +2,26 @@ package exchangerates
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
)
|
||||
|
||||
var e ExchangeRates
|
||||
|
||||
var initialSetup bool
|
||||
|
||||
func setup() {
|
||||
e.Setup(base.Settings{
|
||||
Name: "ExchangeRates",
|
||||
Enabled: true,
|
||||
})
|
||||
initialSetup = true
|
||||
}
|
||||
|
||||
func TestGetLatestRates(t *testing.T) {
|
||||
e.Verbose = true
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
result, err := e.GetLatestRates("USD", "")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to GetLatestRates. Err: %s", err)
|
||||
@@ -40,6 +54,9 @@ func TestGetLatestRates(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCleanCurrencies(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
result := cleanCurrencies("USD", "USD,AUD")
|
||||
if result != "AUD" {
|
||||
t.Fatalf("unexpected result. AUD should be the only symbol")
|
||||
@@ -60,6 +77,9 @@ func TestCleanCurrencies(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetRates(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := e.GetRates("USD", "AUD")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to GetRates. Err: %s", err)
|
||||
@@ -67,7 +87,9 @@ func TestGetRates(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetHistoricalRates(t *testing.T) {
|
||||
e.Verbose = true
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := e.GetHistoricalRates("-1", "USD", []string{"AUD"})
|
||||
if err == nil {
|
||||
t.Fatalf("unexpected result. Invalid date should throw an error")
|
||||
@@ -80,6 +102,9 @@ func TestGetHistoricalRates(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTimeSeriesRates(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := e.GetTimeSeriesRates("", "", "USD", []string{"EUR", "USD"})
|
||||
if err == nil {
|
||||
t.Fatal("unexpected result. Empty startDate endDate params should throw an error")
|
||||
|
||||
@@ -10,11 +10,15 @@ package fixer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -24,22 +28,32 @@ const (
|
||||
fixerAPIProfessionalPlus
|
||||
fixerAPIEnterprise
|
||||
|
||||
fixerAPI = "http://data.fixer.io/api/"
|
||||
fixerAPISSL = "https://data.fixer.io/api/"
|
||||
fixerAPILatest = "latest"
|
||||
fixerAPIConvert = "convert"
|
||||
fixerAPITimeSeries = "timeseries"
|
||||
fixerAPIFluctuation = "fluctuation"
|
||||
fixerAPI = "http://data.fixer.io/api/"
|
||||
fixerAPISSL = "https://data.fixer.io/api/"
|
||||
fixerAPILatest = "latest"
|
||||
fixerAPIConvert = "convert"
|
||||
fixerAPITimeSeries = "timeseries"
|
||||
fixerAPIFluctuation = "fluctuation"
|
||||
fixerSupportedCurrencies = "symbols"
|
||||
|
||||
authRate = 0
|
||||
unAuthRate = 0
|
||||
)
|
||||
|
||||
// Fixer is a foreign exchange rate provider at https://fixer.io/
|
||||
// NOTE DEFAULT BASE CURRENCY IS EUR upgrade to basic to change
|
||||
type Fixer struct {
|
||||
base.Base
|
||||
Requester *request.Requester
|
||||
}
|
||||
|
||||
// Setup sets appropriate values for fixer object
|
||||
func (f *Fixer) Setup(config base.Settings) {
|
||||
func (f *Fixer) Setup(config base.Settings) error {
|
||||
if config.APIKeyLvl < 0 || config.APIKeyLvl > 4 {
|
||||
log.Errorf("apikey incorrectly set in config.json for %s, please set appropriate account levels",
|
||||
config.Name)
|
||||
return errors.New("apikey set failure")
|
||||
}
|
||||
f.APIKey = config.APIKey
|
||||
f.APIKeyLvl = config.APIKeyLvl
|
||||
f.Enabled = config.Enabled
|
||||
@@ -47,6 +61,32 @@ func (f *Fixer) Setup(config base.Settings) {
|
||||
f.RESTPollingDelay = config.RESTPollingDelay
|
||||
f.Verbose = config.Verbose
|
||||
f.PrimaryProvider = config.PrimaryProvider
|
||||
f.Requester = request.New(f.Name,
|
||||
request.NewRateLimit(time.Second*10, authRate),
|
||||
request.NewRateLimit(time.Second*10, unAuthRate),
|
||||
common.NewHTTPClientWithTimeout(base.DefaultTimeOut))
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSupportedCurrencies returns supported currencies
|
||||
func (f *Fixer) GetSupportedCurrencies() ([]string, error) {
|
||||
var resp Symbols
|
||||
|
||||
err := f.SendOpenHTTPRequest(fixerSupportedCurrencies, nil, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !resp.Success {
|
||||
return nil, errors.New(resp.Error.Type + resp.Error.Info)
|
||||
}
|
||||
|
||||
var currencies []string
|
||||
for key := range resp.Map {
|
||||
currencies = append(currencies, key)
|
||||
}
|
||||
|
||||
return currencies, nil
|
||||
}
|
||||
|
||||
// GetRates is a wrapper function to return rates
|
||||
@@ -209,10 +249,19 @@ func (f *Fixer) SendOpenHTTPRequest(endpoint string, v url.Values, result interf
|
||||
var path string
|
||||
v.Set("access_key", f.APIKey)
|
||||
|
||||
var auth bool
|
||||
if f.APIKeyLvl == fixerAPIFree {
|
||||
path = fixerAPI + endpoint + "?" + v.Encode()
|
||||
} else {
|
||||
path = fixerAPISSL + endpoint + "?" + v.Encode()
|
||||
auth = true
|
||||
}
|
||||
return common.SendHTTPGetRequest(path, true, f.Verbose, result)
|
||||
|
||||
return f.Requester.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
auth,
|
||||
f.Verbose)
|
||||
}
|
||||
|
||||
@@ -2,12 +2,8 @@ package fixer
|
||||
|
||||
// Rates contains the data fields for the currencies you have requested.
|
||||
type Rates struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Type string `json:"type"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Success bool `json:"success"`
|
||||
Error RespError `json:"error"`
|
||||
Historical bool `json:"historical"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Base string `json:"base"`
|
||||
@@ -17,13 +13,9 @@ type Rates struct {
|
||||
|
||||
// Conversion contains data for currency conversion
|
||||
type Conversion struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Type string `json:"type"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Query struct {
|
||||
Success bool `json:"success"`
|
||||
Error RespError `json:"error"`
|
||||
Query struct {
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Amount float64 `json:"amount"`
|
||||
@@ -39,12 +31,8 @@ type Conversion struct {
|
||||
|
||||
// TimeSeries holds timeseries data
|
||||
type TimeSeries struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Type string `json:"type"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Success bool `json:"success"`
|
||||
Error RespError `json:"error"`
|
||||
Timeseries bool `json:"timeseries"`
|
||||
StartDate string `json:"start_date"`
|
||||
EndDate string `json:"end_date"`
|
||||
@@ -54,12 +42,8 @@ type TimeSeries struct {
|
||||
|
||||
// Fluctuation holds fluctuation data
|
||||
type Fluctuation struct {
|
||||
Success bool `json:"success"`
|
||||
Error struct {
|
||||
Code int `json:"code"`
|
||||
Type string `json:"type"`
|
||||
Info string `json:"info"`
|
||||
} `json:"error"`
|
||||
Success bool `json:"success"`
|
||||
Error RespError `json:"error"`
|
||||
Fluctuation bool `json:"fluctuation"`
|
||||
StartDate string `json:"start_date"`
|
||||
EndDate string `json:"end_date"`
|
||||
@@ -74,3 +58,17 @@ type Flux struct {
|
||||
Change float64 `json:"change"`
|
||||
ChangePCT float64 `json:"change_pct"`
|
||||
}
|
||||
|
||||
// RespError defines a general resp error sub type
|
||||
type RespError struct {
|
||||
Code int `json:"code"`
|
||||
Type string `json:"type"`
|
||||
Info string `json:"info"`
|
||||
}
|
||||
|
||||
// Symbols defines a symbols list
|
||||
type Symbols struct {
|
||||
Success bool `json:"success"`
|
||||
Error RespError `json:"error"`
|
||||
Map map[string]string `json:"symbols"`
|
||||
}
|
||||
|
||||
@@ -3,68 +3,135 @@
|
||||
package forexprovider
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
currencyconverter "github.com/thrasher-/gocryptotrader/currency/forexprovider/currencyconverterapi"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/currencylayer"
|
||||
exchangerates "github.com/thrasher-/gocryptotrader/currency/forexprovider/exchangeratesapi.io"
|
||||
fixer "github.com/thrasher-/gocryptotrader/currency/forexprovider/fixer.io"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/openexchangerates"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
// ForexProviders is an array of foreign exchange interfaces
|
||||
// ForexProviders is a foreign exchange handler type
|
||||
type ForexProviders struct {
|
||||
base.IFXProviders
|
||||
base.FXHandler
|
||||
}
|
||||
|
||||
// GetAvailableForexProviders returns a list of supported forex providers
|
||||
func GetAvailableForexProviders() []string {
|
||||
return []string{"CurrencyConverter", "CurrencyLayer", "ExchangeRates", "Fixer", "OpenExchangeRates"}
|
||||
return []string{"CurrencyConverter",
|
||||
"CurrencyLayer",
|
||||
"ExchangeRates",
|
||||
"Fixer",
|
||||
"OpenExchangeRates"}
|
||||
}
|
||||
|
||||
// NewDefaultFXProvider returns the default forex provider (currencyconverterAPI)
|
||||
func NewDefaultFXProvider() *ForexProviders {
|
||||
fxp := new(ForexProviders)
|
||||
currencyC := new(exchangerates.ExchangeRates)
|
||||
currencyC.PrimaryProvider = true
|
||||
currencyC.Enabled = true
|
||||
currencyC.Name = "ExchangeRates"
|
||||
fxp.IFXProviders = append(fxp.IFXProviders, currencyC)
|
||||
return fxp
|
||||
handler := new(ForexProviders)
|
||||
provider := new(exchangerates.ExchangeRates)
|
||||
err := provider.Setup(base.Settings{
|
||||
PrimaryProvider: true,
|
||||
Enabled: true,
|
||||
Name: "ExchangeRates",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
currencies, _ := provider.GetSupportedCurrencies()
|
||||
providerBase := base.Provider{
|
||||
Provider: provider,
|
||||
SupportedCurrencies: currencies,
|
||||
}
|
||||
|
||||
handler.FXHandler = base.FXHandler{
|
||||
Primary: providerBase,
|
||||
}
|
||||
|
||||
return handler
|
||||
}
|
||||
|
||||
// SetProvider sets provider to the FX handler
|
||||
func (f *ForexProviders) SetProvider(b base.IFXProvider) error {
|
||||
currencies, err := b.GetSupportedCurrencies()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
providerBase := base.Provider{
|
||||
Provider: b,
|
||||
SupportedCurrencies: currencies,
|
||||
}
|
||||
|
||||
if b.IsPrimaryProvider() {
|
||||
f.FXHandler = base.FXHandler{
|
||||
Primary: providerBase,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
f.FXHandler.Support = append(f.FXHandler.Support, providerBase)
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartFXService starts the forex provider service and returns a pointer to it
|
||||
func StartFXService(fxProviders []base.Settings) *ForexProviders {
|
||||
fxp := new(ForexProviders)
|
||||
func StartFXService(fxProviders []base.Settings) (*ForexProviders, error) {
|
||||
handler := new(ForexProviders)
|
||||
|
||||
for i := range fxProviders {
|
||||
if fxProviders[i].Name == "CurrencyConverter" && fxProviders[i].Enabled {
|
||||
currencyC := new(currencyconverter.CurrencyConverter)
|
||||
currencyC.Setup(fxProviders[i])
|
||||
fxp.IFXProviders = append(fxp.IFXProviders, currencyC)
|
||||
}
|
||||
if fxProviders[i].Name == "CurrencyLayer" && fxProviders[i].Enabled {
|
||||
currencyLayerP := new(currencylayer.CurrencyLayer)
|
||||
currencyLayerP.Setup(fxProviders[i])
|
||||
fxp.IFXProviders = append(fxp.IFXProviders, currencyLayerP)
|
||||
}
|
||||
if fxProviders[i].Name == "ExchangeRates" && fxProviders[i].Enabled {
|
||||
exchangeRatesP := new(exchangerates.ExchangeRates)
|
||||
exchangeRatesP.Setup(fxProviders[i])
|
||||
fxp.IFXProviders = append(fxp.IFXProviders, exchangeRatesP)
|
||||
}
|
||||
if fxProviders[i].Name == "Fixer" && fxProviders[i].Enabled {
|
||||
fixerP := new(fixer.Fixer)
|
||||
fixerP.Setup(fxProviders[i])
|
||||
fxp.IFXProviders = append(fxp.IFXProviders, fixerP)
|
||||
}
|
||||
if fxProviders[i].Name == "OpenExchangeRates" && fxProviders[i].Enabled {
|
||||
OpenExchangeRatesP := new(openexchangerates.OXR)
|
||||
OpenExchangeRatesP.Setup(fxProviders[i])
|
||||
fxp.IFXProviders = append(fxp.IFXProviders, OpenExchangeRatesP)
|
||||
switch {
|
||||
case fxProviders[i].Name == "CurrencyConverter" && fxProviders[i].Enabled:
|
||||
provider := new(currencyconverter.CurrencyConverter)
|
||||
err := provider.Setup(fxProviders[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handler.SetProvider(provider)
|
||||
|
||||
case fxProviders[i].Name == "CurrencyLayer" && fxProviders[i].Enabled:
|
||||
provider := new(currencylayer.CurrencyLayer)
|
||||
err := provider.Setup(fxProviders[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handler.SetProvider(provider)
|
||||
|
||||
case fxProviders[i].Name == "ExchangeRates" && fxProviders[i].Enabled:
|
||||
provider := new(exchangerates.ExchangeRates)
|
||||
err := provider.Setup(fxProviders[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handler.SetProvider(provider)
|
||||
|
||||
case fxProviders[i].Name == "Fixer" && fxProviders[i].Enabled:
|
||||
provider := new(fixer.Fixer)
|
||||
err := provider.Setup(fxProviders[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handler.SetProvider(provider)
|
||||
|
||||
case fxProviders[i].Name == "OpenExchangeRates" && fxProviders[i].Enabled:
|
||||
provider := new(openexchangerates.OXR)
|
||||
err := provider.Setup(fxProviders[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handler.SetProvider(provider)
|
||||
}
|
||||
}
|
||||
if len(fxp.IFXProviders) == 0 {
|
||||
log.Error("No foreign exchange providers enabled")
|
||||
|
||||
if handler.Primary.Provider == nil {
|
||||
return nil, errors.New("no foreign exchange providers enabled")
|
||||
}
|
||||
return fxp
|
||||
|
||||
return handler, nil
|
||||
}
|
||||
|
||||
@@ -14,9 +14,12 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
// These consts contain endpoint information
|
||||
@@ -33,6 +36,21 @@ const (
|
||||
APIEndpointConvert = "convert/%s/%s/%s"
|
||||
APIEndpointOHLC = "ohlc.json"
|
||||
APIEndpointUsage = "usage.json"
|
||||
|
||||
oxrSupportedCurrencies = "AED,AFN,ALL,AMD,ANG,AOA,ARS,AUD,AWG,AZN,BAM,BBD," +
|
||||
"BDT,BGN,BHD,BIF,BMD,BND,BOB,BRL,BSD,BTC,BTN,BWP,BYN,BYR,BZD,CAD,CDF," +
|
||||
"CHF,CLF,CLP,CNH,CNY,COP,CRC,CUC,CUP,CVE,CZK,DJF,DKK,DOP,DZD,EEK,EGP," +
|
||||
"ERN,ETB,EUR,FJD,FKP,GBP,GEL,GGP,GHS,GIP,GMD,GNF,GTQ,GYD,HKD,HNL,HRK," +
|
||||
"HTG,HUF,IDR,ILS,IMP,INR,IQD,IRR,ISK,JEP,JMD,JOD,JPY,KES,KGS,KHR,KMF," +
|
||||
"KPW,KRW,KWD,KYD,KZT,LAK,LBP,LKR,LRD,LSL,LYD,MAD,MDL,MGA,MKD,MMK,MNT," +
|
||||
"MOP,MRO,MRU,MTL,MUR,MVR,MWK,MXN,MYR,MZN,NAD,NGN,NIO,NOK,NPR,NZD,OMR," +
|
||||
"PAB,PEN,PGK,PHP,PKR,PLN,PYG,QAR,RON,RSD,RUB,RWF,SAR,SBD,SCR,SDG,SEK," +
|
||||
"SGD,SHP,SLL,SOS,SRD,SSP,STD,STN,SVC,SYP,SZL,THB,TJS,TMT,TND,TOP,TRY," +
|
||||
"TTD,TWD,TZS,UAH,UGX,USD,UYU,UZS,VEF,VND,VUV,WST,XAF,XAG,XAU,XCD,XDR," +
|
||||
"XOF,XPD,XPF,XPT,YER,ZAR,ZMK,ZMW"
|
||||
|
||||
authRate = 0
|
||||
unAuthRate = 0
|
||||
)
|
||||
|
||||
// OXR is a foreign exchange rate provider at https://openexchangerates.org/
|
||||
@@ -40,10 +58,16 @@ const (
|
||||
// DOCs : https://docs.openexchangerates.org/docs
|
||||
type OXR struct {
|
||||
base.Base
|
||||
Requester *request.Requester
|
||||
}
|
||||
|
||||
// Setup sets values for the OXR object
|
||||
func (o *OXR) Setup(config base.Settings) {
|
||||
func (o *OXR) Setup(config base.Settings) error {
|
||||
if config.APIKeyLvl < 0 || config.APIKeyLvl > 2 {
|
||||
log.Errorf("apikey incorrectly set in config.json for %s, please set appropriate account levels",
|
||||
config.Name)
|
||||
return errors.New("apikey set failure")
|
||||
}
|
||||
o.APIKey = config.APIKey
|
||||
o.APIKeyLvl = config.APIKeyLvl
|
||||
o.Enabled = config.Enabled
|
||||
@@ -51,6 +75,11 @@ func (o *OXR) Setup(config base.Settings) {
|
||||
o.RESTPollingDelay = config.RESTPollingDelay
|
||||
o.Verbose = config.Verbose
|
||||
o.PrimaryProvider = config.PrimaryProvider
|
||||
o.Requester = request.New(o.Name,
|
||||
request.NewRateLimit(time.Second*10, authRate),
|
||||
request.NewRateLimit(time.Second*10, unAuthRate),
|
||||
common.NewHTTPClientWithTimeout(base.DefaultTimeOut))
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRates is a wrapper function to return rates
|
||||
@@ -125,6 +154,11 @@ func (o *OXR) GetCurrencies(showInactive, prettyPrint, showAlternative bool) (ma
|
||||
return resp, o.SendHTTPRequest(APIEndpointCurrencies, v, &resp)
|
||||
}
|
||||
|
||||
// GetSupportedCurrencies returns a list of supported currencies
|
||||
func (o *OXR) GetSupportedCurrencies() ([]string, error) {
|
||||
return common.SplitStrings(oxrSupportedCurrencies, ","), nil
|
||||
}
|
||||
|
||||
// GetTimeSeries returns historical exchange rates for a given time period,
|
||||
// where available.
|
||||
func (o *OXR) GetTimeSeries(baseCurrency, startDate, endDate string, symbols []string, prettyPrint, showAlternative bool) (map[string]interface{}, error) {
|
||||
@@ -223,9 +257,11 @@ func (o *OXR) SendHTTPRequest(endpoint string, values url.Values, result interfa
|
||||
headers["Authorization"] = "Token " + o.APIKey
|
||||
path := APIURL + endpoint + "?" + values.Encode()
|
||||
|
||||
resp, err := common.SendHTTPRequest(http.MethodGet, path, headers, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return common.JSONDecode([]byte(resp), result)
|
||||
return o.Requester.SendPayload(http.MethodGet,
|
||||
path,
|
||||
headers,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
o.Verbose)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package openexchangerates
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
)
|
||||
|
||||
// please set apikey for due diligence testing NOTE testing uses your allocated
|
||||
@@ -13,7 +15,20 @@ const (
|
||||
|
||||
var o OXR
|
||||
|
||||
var initialSetup bool
|
||||
|
||||
func setup() {
|
||||
o.Setup(base.Settings{
|
||||
Name: "OpenExchangeRates",
|
||||
Enabled: true,
|
||||
})
|
||||
initialSetup = true
|
||||
}
|
||||
|
||||
func TestGetRates(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := o.GetRates("USD", "AUD")
|
||||
if err == nil {
|
||||
t.Error("test failed - GetRates() error", err)
|
||||
@@ -21,6 +36,9 @@ func TestGetRates(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetLatest(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := o.GetLatest("USD", "AUD", false, false)
|
||||
if err == nil {
|
||||
t.Error("test failed - GetLatest() error", err)
|
||||
@@ -28,6 +46,9 @@ func TestGetLatest(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetHistoricalRates(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := o.GetHistoricalRates("2017-12-01", "USD", []string{"CNH", "AUD", "ANG"}, false, false)
|
||||
if err == nil {
|
||||
t.Error("test failed - GetRates() error", err)
|
||||
@@ -35,6 +56,9 @@ func TestGetHistoricalRates(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetCurrencies(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := o.GetCurrencies(true, true, true)
|
||||
if err != nil {
|
||||
t.Error("test failed - GetCurrencies() error", err)
|
||||
@@ -42,6 +66,9 @@ func TestGetCurrencies(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTimeSeries(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := o.GetTimeSeries("USD", "2017-12-01", "2017-12-02", []string{"CNH", "AUD", "ANG"}, false, false)
|
||||
if err == nil {
|
||||
t.Error("test failed - GetTimeSeries() error", err)
|
||||
@@ -49,6 +76,9 @@ func TestGetTimeSeries(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConvertCurrency(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := o.ConvertCurrency(1337, "USD", "AUD")
|
||||
if err == nil {
|
||||
t.Error("test failed - ConvertCurrency() error", err)
|
||||
@@ -56,6 +86,9 @@ func TestConvertCurrency(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetOHLC(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := o.GetOHLC("2017-07-17T08:30:00Z", "1m", "USD", []string{"AUD"}, false)
|
||||
if err == nil {
|
||||
t.Error("test failed - GetOHLC() error", err)
|
||||
@@ -63,6 +96,9 @@ func TestGetOHLC(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetUsageStats(t *testing.T) {
|
||||
if !initialSetup {
|
||||
setup()
|
||||
}
|
||||
_, err := o.GetUsageStats(false)
|
||||
if err == nil {
|
||||
t.Error("test failed - GetUsageStats() error", err)
|
||||
|
||||
190
currency/pair.go
Normal file
190
currency/pair.go
Normal file
@@ -0,0 +1,190 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
// NewPairDelimiter splits the desired currency string at delimeter, the returns
|
||||
// a Pair struct
|
||||
func NewPairDelimiter(currencyPair, delimiter string) Pair {
|
||||
result := strings.Split(currencyPair, delimiter)
|
||||
return Pair{
|
||||
Delimiter: delimiter,
|
||||
Base: NewCode(result[0]),
|
||||
Quote: NewCode(result[1]),
|
||||
}
|
||||
}
|
||||
|
||||
// NewPairFromStrings returns a CurrencyPair without a delimiter
|
||||
func NewPairFromStrings(baseCurrency, quoteCurrency string) Pair {
|
||||
return Pair{
|
||||
Base: NewCode(baseCurrency),
|
||||
Quote: NewCode(quoteCurrency),
|
||||
}
|
||||
}
|
||||
|
||||
// NewPair returns a currency pair from currency codes
|
||||
func NewPair(baseCurrency, quoteCurrency Code) Pair {
|
||||
return Pair{
|
||||
Base: baseCurrency,
|
||||
Quote: quoteCurrency,
|
||||
}
|
||||
}
|
||||
|
||||
// NewPairWithDelimiter returns a CurrencyPair with a delimiter
|
||||
func NewPairWithDelimiter(base, quote, delimiter string) Pair {
|
||||
return Pair{
|
||||
Base: NewCode(base),
|
||||
Quote: NewCode(quote),
|
||||
Delimiter: delimiter,
|
||||
}
|
||||
}
|
||||
|
||||
// NewPairFromIndex returns a CurrencyPair via a currency string and specific
|
||||
// index
|
||||
func NewPairFromIndex(currencyPair, index string) (Pair, error) {
|
||||
i := strings.Index(currencyPair, index)
|
||||
if i == -1 {
|
||||
return Pair{},
|
||||
fmt.Errorf("index %s not found in currency pair string", index)
|
||||
}
|
||||
if i == 0 {
|
||||
return NewPairFromStrings(currencyPair[0:len(index)],
|
||||
currencyPair[len(index):]),
|
||||
nil
|
||||
}
|
||||
return NewPairFromStrings(currencyPair[0:i], currencyPair[i:]), nil
|
||||
}
|
||||
|
||||
// NewPairFromString converts currency string into a new CurrencyPair
|
||||
// with or without delimeter
|
||||
func NewPairFromString(currencyPair string) Pair {
|
||||
delimiters := []string{"_", "-"}
|
||||
var delimiter string
|
||||
for _, x := range delimiters {
|
||||
if strings.Contains(currencyPair, x) {
|
||||
delimiter = x
|
||||
return NewPairDelimiter(currencyPair, delimiter)
|
||||
}
|
||||
}
|
||||
return NewPairFromStrings(currencyPair[0:3], currencyPair[3:])
|
||||
}
|
||||
|
||||
// Pair holds currency pair information
|
||||
type Pair struct {
|
||||
Delimiter string `json:"delimiter"`
|
||||
Base Code `json:"base"`
|
||||
Quote Code `json:"quote"`
|
||||
}
|
||||
|
||||
// String returns a currency pair string
|
||||
func (p Pair) String() string {
|
||||
return p.Base.String() + p.Delimiter + p.Quote.String()
|
||||
}
|
||||
|
||||
// Lower converts the pair object to lowercase
|
||||
func (p Pair) Lower() Pair {
|
||||
return Pair{
|
||||
Delimiter: p.Delimiter,
|
||||
Base: p.Base.Lower(),
|
||||
Quote: p.Quote.Lower(),
|
||||
}
|
||||
}
|
||||
|
||||
// Upper converts the pair object to uppercase
|
||||
func (p Pair) Upper() Pair {
|
||||
return Pair{
|
||||
Delimiter: p.Delimiter,
|
||||
Base: p.Base.Upper(),
|
||||
Quote: p.Quote.Upper(),
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON comforms type to the umarshaler interface
|
||||
func (p *Pair) UnmarshalJSON(d []byte) error {
|
||||
var pair string
|
||||
err := common.JSONDecode(d, &pair)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*p = NewPairFromString(pair)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON conforms type to the marshaler interface
|
||||
func (p Pair) MarshalJSON() ([]byte, error) {
|
||||
return common.JSONEncode(p.String())
|
||||
}
|
||||
|
||||
// Format changes the currency based on user preferences overriding the default
|
||||
// String() display
|
||||
func (p Pair) Format(delimiter string, uppercase bool) Pair {
|
||||
p.Delimiter = delimiter
|
||||
|
||||
if uppercase {
|
||||
return p.Upper()
|
||||
}
|
||||
return p.Lower()
|
||||
}
|
||||
|
||||
// Equal compares two currency pairs and returns whether or not they are equal
|
||||
func (p Pair) Equal(cPair Pair) bool {
|
||||
return p.Base.Item == cPair.Base.Item && p.Quote.Item == cPair.Quote.Item
|
||||
}
|
||||
|
||||
// EqualIncludeReciprocal compares two currency pairs and returns whether or not
|
||||
// they are the same including reciprocal currencies.
|
||||
func (p Pair) EqualIncludeReciprocal(cPair Pair) bool {
|
||||
if p.Base.Item == cPair.Base.Item &&
|
||||
p.Quote.Item == cPair.Quote.Item ||
|
||||
p.Base.Item == cPair.Quote.Item &&
|
||||
p.Quote.Item == cPair.Base.Item {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCryptoPair checks to see if the pair is a crypto pair e.g. BTCLTC
|
||||
func (p Pair) IsCryptoPair() bool {
|
||||
return storage.IsCryptocurrency(p.Base) &&
|
||||
storage.IsCryptocurrency(p.Quote)
|
||||
}
|
||||
|
||||
// IsCryptoFiatPair checks to see if the pair is a crypto fiat pair e.g. BTCUSD
|
||||
func (p Pair) IsCryptoFiatPair() bool {
|
||||
return storage.IsCryptocurrency(p.Base) &&
|
||||
storage.IsFiatCurrency(p.Quote) ||
|
||||
storage.IsFiatCurrency(p.Base) &&
|
||||
storage.IsCryptocurrency(p.Quote)
|
||||
}
|
||||
|
||||
// IsFiatPair checks to see if the pair is a fiat pair e.g. EURUSD
|
||||
func (p Pair) IsFiatPair() bool {
|
||||
return storage.IsFiatCurrency(p.Base) && storage.IsFiatCurrency(p.Quote)
|
||||
}
|
||||
|
||||
// IsInvalid checks invalid pair if base and quote are the same
|
||||
func (p Pair) IsInvalid() bool {
|
||||
return p.Base.Item == p.Quote.Item
|
||||
}
|
||||
|
||||
// Swap turns the currency pair into its reciprocal
|
||||
func (p Pair) Swap() Pair {
|
||||
p.Base, p.Quote = p.Quote, p.Base
|
||||
return p
|
||||
}
|
||||
|
||||
// IsEmpty returns whether or not the pair is empty or is missing a currency
|
||||
// code
|
||||
func (p Pair) IsEmpty() bool {
|
||||
return p.Base.IsEmpty() || p.Quote.IsEmpty()
|
||||
}
|
||||
|
||||
// ContainsCurrency checks to see if a pair contains a specific currency
|
||||
func (p Pair) ContainsCurrency(c Code) bool {
|
||||
return p.Base.Item == c.Item || p.Quote.Item == c.Item
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
# GoCryptoTrader package Pair
|
||||
|
||||
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/page-logo.png?raw=true" width="350px" height="350px" hspace="70">
|
||||
|
||||
|
||||
[](https://travis-ci.org/thrasher-/gocryptotrader)
|
||||
[](https://github.com/thrasher-/gocryptotrader/blob/master/LICENSE)
|
||||
[](https://godoc.org/github.com/thrasher-/gocryptotrader/currency/pair)
|
||||
[](http://codecov.io/github/thrasher-/gocryptotrader?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/thrasher-/gocryptotrader)
|
||||
|
||||
|
||||
This pair package is part of the GoCryptoTrader codebase.
|
||||
|
||||
## This is still in active development
|
||||
|
||||
You can track ideas, planned features and what's in progresss on this Trello board: [https://trello.com/b/ZAhMhpOy/gocryptotrader](https://trello.com/b/ZAhMhpOy/gocryptotrader).
|
||||
|
||||
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTQyYjIxNGVhMWU5MDZlOGYzMmE0NTJmM2MzYWY5NGMzMmM4MzUwNTBjZTEzNjIwODM5NDcxODQwZDljMGQyNGY)
|
||||
|
||||
## Current Features for pair
|
||||
|
||||
+ Provides a new data structure for a currency pair
|
||||
+ Methods to manipulate, create and retrieve different parts of the currency pair
|
||||
|
||||
+ Example below:
|
||||
```go
|
||||
import "github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
|
||||
// Create new pair
|
||||
newPair := pair.NewCurrencyPair("BTC", "USD")
|
||||
|
||||
// Retrieve different parts of the pair
|
||||
bitcoinString := newPair.GetFirstCurrency
|
||||
```
|
||||
|
||||
### Please click GoDocs chevron above to view current GoDoc information for this package
|
||||
|
||||
## Contribution
|
||||
|
||||
Please feel free to submit any pull requests or suggest any desired features to be added.
|
||||
|
||||
When submitting a PR, please abide by our coding guidelines:
|
||||
|
||||
+ Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)).
|
||||
+ Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines.
|
||||
+ Code must adhere to our [coding style](https://github.com/thrasher-/gocryptotrader/blob/master/doc/coding_style.md).
|
||||
+ Pull requests need to be based on and opened against the `master` branch.
|
||||
|
||||
## Donations
|
||||
|
||||
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/donate.png?raw=true" hspace="70">
|
||||
|
||||
If this framework helped you in any way, or you would like to support the developers working on it, please donate Bitcoin to:
|
||||
|
||||
***1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB***
|
||||
|
||||
@@ -1,246 +0,0 @@
|
||||
package pair
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
// CurrencyItem is an exported string with methods to manipulate the data instead
|
||||
// of using array/slice access modifiers
|
||||
type CurrencyItem string
|
||||
|
||||
// Lower converts the CurrencyItem object c to lowercase
|
||||
func (c CurrencyItem) Lower() CurrencyItem {
|
||||
return CurrencyItem(strings.ToLower(string(c)))
|
||||
}
|
||||
|
||||
// Upper converts the CurrencyItem object c to uppercase
|
||||
func (c CurrencyItem) Upper() CurrencyItem {
|
||||
return CurrencyItem(strings.ToUpper(string(c)))
|
||||
}
|
||||
|
||||
// String converts the CurrencyItem object c to string
|
||||
func (c CurrencyItem) String() string {
|
||||
return string(c)
|
||||
}
|
||||
|
||||
// CurrencyPair holds currency pair information
|
||||
type CurrencyPair struct {
|
||||
Delimiter string `json:"delimiter"`
|
||||
FirstCurrency CurrencyItem `json:"first_currency"`
|
||||
SecondCurrency CurrencyItem `json:"second_currency"`
|
||||
}
|
||||
|
||||
// Pair returns a currency pair string
|
||||
func (c CurrencyPair) Pair() CurrencyItem {
|
||||
return c.FirstCurrency + CurrencyItem(c.Delimiter) + c.SecondCurrency
|
||||
}
|
||||
|
||||
// Display formats and returns the currency based on user preferences,
|
||||
// overriding the default Pair() display
|
||||
func (c CurrencyPair) Display(delimiter string, uppercase bool) CurrencyItem {
|
||||
var pair CurrencyItem
|
||||
|
||||
if delimiter != "" {
|
||||
pair = c.FirstCurrency + CurrencyItem(delimiter) + c.SecondCurrency
|
||||
} else {
|
||||
pair = c.FirstCurrency + c.SecondCurrency
|
||||
}
|
||||
|
||||
if uppercase {
|
||||
return pair.Upper()
|
||||
}
|
||||
return pair.Lower()
|
||||
}
|
||||
|
||||
// Equal compares two currency pairs and returns whether or not they are equal
|
||||
func (c CurrencyPair) Equal(p CurrencyPair, exact bool) bool {
|
||||
if !exact {
|
||||
if c.FirstCurrency.Upper() == p.FirstCurrency.Upper() &&
|
||||
c.SecondCurrency.Upper() == p.SecondCurrency.Upper() ||
|
||||
c.FirstCurrency.Upper() == p.SecondCurrency.Upper() &&
|
||||
c.SecondCurrency.Upper() == p.FirstCurrency.Upper() {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if c.FirstCurrency.Upper() == p.FirstCurrency.Upper() &&
|
||||
c.SecondCurrency.Upper() == p.SecondCurrency.Upper() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Swap swaps the pairs first and second currencies
|
||||
func (c CurrencyPair) Swap() CurrencyPair {
|
||||
p := c
|
||||
p.FirstCurrency = c.SecondCurrency
|
||||
p.SecondCurrency = c.FirstCurrency
|
||||
return p
|
||||
}
|
||||
|
||||
// Empty returns whether or not the pair is empty
|
||||
func (c CurrencyPair) Empty() bool {
|
||||
if c.FirstCurrency == "" || c.SecondCurrency == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NewCurrencyPairDelimiter splits the desired currency string at delimeter,
|
||||
// the returns a CurrencyPair struct
|
||||
func NewCurrencyPairDelimiter(currency, delimiter string) CurrencyPair {
|
||||
result := strings.Split(currency, delimiter)
|
||||
return CurrencyPair{
|
||||
Delimiter: delimiter,
|
||||
FirstCurrency: CurrencyItem(result[0]),
|
||||
SecondCurrency: CurrencyItem(result[1]),
|
||||
}
|
||||
}
|
||||
|
||||
// NewCurrencyPair returns a CurrencyPair without a delimiter
|
||||
func NewCurrencyPair(firstCurrency, secondCurrency string) CurrencyPair {
|
||||
return CurrencyPair{
|
||||
FirstCurrency: CurrencyItem(firstCurrency),
|
||||
SecondCurrency: CurrencyItem(secondCurrency),
|
||||
}
|
||||
}
|
||||
|
||||
// NewCurrencyPairWithDelimiter returns a CurrencyPair with a delimiter
|
||||
func NewCurrencyPairWithDelimiter(firstCurrency, secondCurrency, delimiter string) CurrencyPair {
|
||||
return CurrencyPair{
|
||||
FirstCurrency: CurrencyItem(firstCurrency),
|
||||
SecondCurrency: CurrencyItem(secondCurrency),
|
||||
Delimiter: delimiter,
|
||||
}
|
||||
}
|
||||
|
||||
// NewCurrencyPairFromIndex returns a CurrencyPair via a currency string and
|
||||
// specific index
|
||||
func NewCurrencyPairFromIndex(currency, index string) CurrencyPair {
|
||||
i := strings.Index(currency, index)
|
||||
if i == 0 {
|
||||
return NewCurrencyPair(currency[0:len(index)], currency[len(index):])
|
||||
}
|
||||
return NewCurrencyPair(currency[0:i], currency[i:])
|
||||
}
|
||||
|
||||
// NewCurrencyPairFromString converts currency string into a new CurrencyPair
|
||||
// with or without delimeter
|
||||
func NewCurrencyPairFromString(currency string) CurrencyPair {
|
||||
delimiters := []string{"_", "-"}
|
||||
var delimiter string
|
||||
for _, x := range delimiters {
|
||||
if strings.Contains(currency, x) {
|
||||
delimiter = x
|
||||
return NewCurrencyPairDelimiter(currency, delimiter)
|
||||
}
|
||||
}
|
||||
return NewCurrencyPair(currency[0:3], currency[3:])
|
||||
}
|
||||
|
||||
// Contains checks to see if a specified pair exists inside a currency pair
|
||||
// array
|
||||
func Contains(pairs []CurrencyPair, p CurrencyPair, exact bool) bool {
|
||||
for x := range pairs {
|
||||
if pairs[x].Equal(p, exact) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ContainsCurrency checks to see if a pair contains a specific currency
|
||||
func ContainsCurrency(p CurrencyPair, c string) bool {
|
||||
return p.FirstCurrency.Upper().String() == common.StringToUpper(c) ||
|
||||
p.SecondCurrency.Upper().String() == common.StringToUpper(c)
|
||||
}
|
||||
|
||||
// RemovePairsByFilter checks to see if a pair contains a specific currency
|
||||
// and removes it from the list of pairs
|
||||
func RemovePairsByFilter(p []CurrencyPair, filter string) []CurrencyPair {
|
||||
var pairs []CurrencyPair
|
||||
for x := range p {
|
||||
if ContainsCurrency(p[x], filter) {
|
||||
continue
|
||||
}
|
||||
pairs = append(pairs, p[x])
|
||||
}
|
||||
return pairs
|
||||
}
|
||||
|
||||
// FormatPairs formats a string array to a list of currency pairs with the
|
||||
// supplied currency pair format
|
||||
func FormatPairs(pairs []string, delimiter, index string) []CurrencyPair {
|
||||
var result []CurrencyPair
|
||||
for x := range pairs {
|
||||
if pairs[x] == "" {
|
||||
continue
|
||||
}
|
||||
var p CurrencyPair
|
||||
if delimiter != "" {
|
||||
p = NewCurrencyPairDelimiter(pairs[x], delimiter)
|
||||
} else {
|
||||
if index != "" {
|
||||
p = NewCurrencyPairFromIndex(pairs[x], index)
|
||||
} else {
|
||||
p = NewCurrencyPair(pairs[x][0:3], pairs[x][3:])
|
||||
}
|
||||
}
|
||||
result = append(result, p)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// CopyPairFormat copies the pair format from a list of pairs once matched
|
||||
func CopyPairFormat(p CurrencyPair, pairs []CurrencyPair, exact bool) CurrencyPair {
|
||||
for x := range pairs {
|
||||
if p.Equal(pairs[x], exact) {
|
||||
return pairs[x]
|
||||
}
|
||||
}
|
||||
return CurrencyPair{}
|
||||
}
|
||||
|
||||
// FindPairDifferences returns pairs which are new or have been removed
|
||||
func FindPairDifferences(oldPairs, newPairs []string) (newPs, removedPs []string) {
|
||||
for x := range newPairs {
|
||||
if newPairs[x] == "" {
|
||||
continue
|
||||
}
|
||||
if !common.StringDataCompareUpper(oldPairs, newPairs[x]) {
|
||||
newPs = append(newPs, newPairs[x])
|
||||
}
|
||||
}
|
||||
for x := range oldPairs {
|
||||
if oldPairs[x] == "" {
|
||||
continue
|
||||
}
|
||||
if !common.StringDataCompareUpper(newPairs, oldPairs[x]) {
|
||||
removedPs = append(removedPs, oldPairs[x])
|
||||
}
|
||||
}
|
||||
return newPs, removedPs
|
||||
}
|
||||
|
||||
// PairsToStringArray returns a list of pairs as a string array
|
||||
func PairsToStringArray(pairs []CurrencyPair) []string {
|
||||
var p []string
|
||||
for x := range pairs {
|
||||
p = append(p, pairs[x].Pair().String())
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// RandomPairFromPairs returns a random pair from a list of pairs
|
||||
func RandomPairFromPairs(pairs []CurrencyPair) CurrencyPair {
|
||||
pairsLen := len(pairs)
|
||||
|
||||
if pairsLen == 0 {
|
||||
return CurrencyPair{}
|
||||
}
|
||||
|
||||
return pairs[rand.Intn(pairsLen)]
|
||||
}
|
||||
@@ -1,440 +0,0 @@
|
||||
package pair
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLower(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := CurrencyItem("BTCUSD")
|
||||
actual := pair.Lower()
|
||||
expected := CurrencyItem("btcusd")
|
||||
if actual != expected {
|
||||
t.Errorf("Test failed. Lower(): %s was not equal to expected value: %s",
|
||||
actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpper(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := CurrencyItem("btcusd")
|
||||
actual := pair.Upper()
|
||||
expected := CurrencyItem("BTCUSD")
|
||||
if actual != expected {
|
||||
t.Errorf("Test failed. Upper(): %s was not equal to expected value: %s",
|
||||
actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPair("BTC", "USD")
|
||||
actual := "BTCUSD"
|
||||
expected := pair.Pair().String()
|
||||
if actual != expected {
|
||||
t.Errorf("Test failed. String(): %s was not equal to expected value: %s",
|
||||
actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFirstCurrency(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPair("BTC", "USD")
|
||||
actual := pair.FirstCurrency
|
||||
expected := CurrencyItem("BTC")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. GetFirstCurrency(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecondCurrency(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPair("BTC", "USD")
|
||||
actual := pair.SecondCurrency
|
||||
expected := CurrencyItem("USD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. GetSecondCurrency(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPair(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPair("BTC", "USD")
|
||||
actual := pair.Pair()
|
||||
expected := CurrencyItem("BTCUSD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisplay(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPairDelimiter("BTC-USD", "-")
|
||||
actual := pair.Pair()
|
||||
expected := CurrencyItem("BTC-USD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
actual = pair.Display("", false)
|
||||
expected = CurrencyItem("btcusd")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
actual = pair.Display("~", true)
|
||||
expected = CurrencyItem("BTC~USD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPair("BTC", "USD")
|
||||
secondPair := NewCurrencyPair("btc", "uSd")
|
||||
actual := pair.Equal(secondPair, false)
|
||||
expected := true
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Equal(): %v was not equal to expected value: %v",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
secondPair.SecondCurrency = "ETH"
|
||||
actual = pair.Equal(secondPair, false)
|
||||
expected = false
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Equal(): %v was not equal to expected value: %v",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
secondPair = NewCurrencyPair("USD", "BTC")
|
||||
actual = pair.Equal(secondPair, false)
|
||||
expected = true
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Equal(): %v was not equal to expected value: %v",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwap(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPair("BTC", "USD")
|
||||
actual := pair.Swap().Pair()
|
||||
expected := CurrencyItem("USDBTC")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. TestSwap: %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPair("BTC", "USD")
|
||||
if pair.Empty() {
|
||||
t.Error("Test failed. Empty() returned true when the pair was initialised")
|
||||
}
|
||||
|
||||
var p CurrencyPair
|
||||
if !p.Empty() {
|
||||
t.Error("Test failed. Empty() returned true when the pair wasn't initialised")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewCurrencyPair(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPair("BTC", "USD")
|
||||
actual := pair.Pair()
|
||||
expected := CurrencyItem("BTCUSD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewCurrencyPairWithDelimiter(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPairWithDelimiter("BTC", "USD", "-test-")
|
||||
actual := pair.Pair()
|
||||
expected := CurrencyItem("BTC-test-USD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
pair = NewCurrencyPairWithDelimiter("BTC", "USD", "")
|
||||
actual = pair.Pair()
|
||||
expected = CurrencyItem("BTCUSD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewCurrencyPairDelimiter(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewCurrencyPairDelimiter("BTC-USD", "-")
|
||||
actual := pair.Pair()
|
||||
expected := CurrencyItem("BTC-USD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
actual = CurrencyItem(pair.Delimiter)
|
||||
expected = "-"
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Delmiter: %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// TestNewCurrencyPairFromIndex returns a CurrencyPair via a currency string and
|
||||
// specific index
|
||||
func TestNewCurrencyPairFromIndex(t *testing.T) {
|
||||
t.Parallel()
|
||||
currency := "BTCUSD"
|
||||
index := "BTC"
|
||||
|
||||
pair := NewCurrencyPairFromIndex(currency, index)
|
||||
pair.Delimiter = "-"
|
||||
actual := pair.Pair()
|
||||
|
||||
expected := CurrencyItem("BTC-USD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
currency = "DOGEBTC"
|
||||
|
||||
pair = NewCurrencyPairFromIndex(currency, index)
|
||||
pair.Delimiter = "-"
|
||||
actual = pair.Pair()
|
||||
|
||||
expected = CurrencyItem("DOGE-BTC")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewCurrencyPairFromString(t *testing.T) {
|
||||
t.Parallel()
|
||||
pairStr := "BTC-USD"
|
||||
pair := NewCurrencyPairFromString(pairStr)
|
||||
actual := pair.Pair()
|
||||
expected := CurrencyItem("BTC-USD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
pairStr = "BTCUSD"
|
||||
pair = NewCurrencyPairFromString(pairStr)
|
||||
actual = pair.Pair()
|
||||
expected = CurrencyItem("BTCUSD")
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContains(t *testing.T) {
|
||||
pairOne := NewCurrencyPair("BTC", "USD")
|
||||
|
||||
var pairs []CurrencyPair
|
||||
pairs = append(pairs, pairOne, NewCurrencyPair("LTC", "USD"))
|
||||
|
||||
if !Contains(pairs, pairOne, true) {
|
||||
t.Errorf("Test failed. TestContains: Expected pair was not found")
|
||||
}
|
||||
|
||||
if Contains(pairs, NewCurrencyPair("ETH", "USD"), false) {
|
||||
t.Errorf("Test failed. TestContains: Non-existent pair was found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsCurrency(t *testing.T) {
|
||||
p := NewCurrencyPair("BTC", "USD")
|
||||
|
||||
if !ContainsCurrency(p, "BTC") {
|
||||
t.Error("Test failed. TestContainsCurrency: Expected currency was not found")
|
||||
}
|
||||
|
||||
if ContainsCurrency(p, "ETH") {
|
||||
t.Error("Test failed. TestContainsCurrency: Non-existent currency was found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemovePairsByFilter(t *testing.T) {
|
||||
var pairs []CurrencyPair
|
||||
pairs = append(pairs, NewCurrencyPair("BTC", "USD"),
|
||||
NewCurrencyPair("LTC", "USD"),
|
||||
NewCurrencyPair("LTC", "USDT"))
|
||||
|
||||
pairs = RemovePairsByFilter(pairs, "USDT")
|
||||
if Contains(pairs, NewCurrencyPair("LTC", "USDT"), true) {
|
||||
t.Error("Test failed. TestRemovePairsByFilter unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatPairs(t *testing.T) {
|
||||
if len(FormatPairs([]string{""}, "-", "")) > 0 {
|
||||
t.Error("Test failed. TestFormatPairs: Empty string returned a valid pair")
|
||||
}
|
||||
|
||||
if FormatPairs([]string{"BTC-USD"}, "-", "")[0].Pair().String() != "BTC-USD" {
|
||||
t.Error("Test failed. TestFormatPairs: Expected pair was not found")
|
||||
}
|
||||
|
||||
if FormatPairs([]string{"BTCUSD"}, "", "BTC")[0].Pair().String() != "BTCUSD" {
|
||||
t.Error("Test failed. TestFormatPairs: Expected pair was not found")
|
||||
}
|
||||
|
||||
if FormatPairs([]string{"ETHUSD"}, "", "")[0].Pair().String() != "ETHUSD" {
|
||||
t.Error("Test failed. TestFormatPairs: Expected pair was not found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCopyPairFormat(t *testing.T) {
|
||||
pairOne := NewCurrencyPair("BTC", "USD")
|
||||
pairOne.Delimiter = "-"
|
||||
|
||||
var pairs []CurrencyPair
|
||||
pairs = append(pairs, pairOne, NewCurrencyPair("LTC", "USD"))
|
||||
|
||||
testPair := NewCurrencyPair("BTC", "USD")
|
||||
testPair.Delimiter = "~"
|
||||
|
||||
result := CopyPairFormat(testPair, pairs, false)
|
||||
if result.Pair().String() != "BTC-USD" {
|
||||
t.Error("Test failed. TestCopyPairFormat: Expected pair was not found")
|
||||
}
|
||||
|
||||
result = CopyPairFormat(NewCurrencyPair("ETH", "USD"), pairs, true)
|
||||
if result.Pair().String() != "" {
|
||||
t.Error("Test failed. TestCopyPairFormat: Unexpected non empty pair returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindPairDifferences(t *testing.T) {
|
||||
pairList := []string{"BTC-USD", "ETH-USD", "LTC-USD"}
|
||||
|
||||
// Test new pair update
|
||||
newPairs, removedPairs := FindPairDifferences(pairList, []string{"DASH-USD"})
|
||||
if len(newPairs) != 1 && len(removedPairs) != 3 {
|
||||
t.Error("Test failed. TestFindPairDifferences: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that we don't allow empty strings for new pairs
|
||||
newPairs, removedPairs = FindPairDifferences(pairList, []string{""})
|
||||
if len(newPairs) != 0 && len(removedPairs) != 3 {
|
||||
t.Error("Test failed. TestFindPairDifferences: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that we don't allow empty strings for new pairs
|
||||
newPairs, removedPairs = FindPairDifferences([]string{""}, pairList)
|
||||
if len(newPairs) != 3 && len(removedPairs) != 0 {
|
||||
t.Error("Test failed. TestFindPairDifferences: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that the supplied pair lists are the same, so
|
||||
// no newPairs or removedPairs
|
||||
newPairs, removedPairs = FindPairDifferences(pairList, pairList)
|
||||
if len(newPairs) != 0 && len(removedPairs) != 0 {
|
||||
t.Error("Test failed. TestFindPairDifferences: Unexpected values")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPairsToStringArray(t *testing.T) {
|
||||
var pairs []CurrencyPair
|
||||
pairs = append(pairs, NewCurrencyPair("BTC", "USD"))
|
||||
|
||||
expected := []string{"BTCUSD"}
|
||||
actual := PairsToStringArray(pairs)
|
||||
|
||||
if actual[0] != expected[0] {
|
||||
t.Error("Test failed. TestPairsToStringArray: Unexpected values")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandomPairFromPairs(t *testing.T) {
|
||||
// Test that an empty pairs array returns an empty currency pair
|
||||
result := RandomPairFromPairs([]CurrencyPair{})
|
||||
if !result.Empty() {
|
||||
t.Error("Test failed. TestRandomPairFromPairs: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that a populated pairs array returns a non-empty currency pair
|
||||
var pairs []CurrencyPair
|
||||
pairs = append(pairs, NewCurrencyPair("BTC", "USD"))
|
||||
result = RandomPairFromPairs(pairs)
|
||||
|
||||
if result.Empty() {
|
||||
t.Error("Test failed. TestRandomPairFromPairs: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that a populated pairs array over a number of attempts returns ALL
|
||||
// currency pairs
|
||||
pairs = append(pairs, NewCurrencyPair("ETH", "USD"))
|
||||
expectedResults := make(map[string]bool)
|
||||
for i := 0; i < 50; i++ {
|
||||
p := RandomPairFromPairs(pairs).Pair().String()
|
||||
_, ok := expectedResults[p]
|
||||
if !ok {
|
||||
expectedResults[p] = true
|
||||
}
|
||||
}
|
||||
|
||||
for x := range pairs {
|
||||
_, ok := expectedResults[pairs[x].Pair().String()]
|
||||
if !ok {
|
||||
t.Error("Test failed. TestRandomPairFromPairs: Unexpected values")
|
||||
}
|
||||
}
|
||||
}
|
||||
563
currency/pair_test.go
Normal file
563
currency/pair_test.go
Normal file
@@ -0,0 +1,563 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultPair = "BTCUSD"
|
||||
defaultPairWDelimiter = "BTC-USD"
|
||||
)
|
||||
|
||||
func TestLower(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPairFromString(defaultPair)
|
||||
actual := pair.Lower()
|
||||
expected := NewPairFromString(defaultPair).Lower()
|
||||
if actual != expected {
|
||||
t.Errorf("Test failed. Lower(): %s was not equal to expected value: %s",
|
||||
actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpper(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPairFromString(defaultPair)
|
||||
actual := pair.Upper()
|
||||
expected := NewPairFromString(defaultPair)
|
||||
if actual != expected {
|
||||
t.Errorf("Test failed. Upper(): %s was not equal to expected value: %s",
|
||||
actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPairUnmarshalJSON(t *testing.T) {
|
||||
var unmarshalHere Pair
|
||||
configPair := NewPairDelimiter("btc_usd", "_")
|
||||
|
||||
encoded, err := common.JSONEncode(configPair)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Pair UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
err = common.JSONDecode(encoded, &unmarshalHere)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Pair UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
err = common.JSONDecode(encoded, &unmarshalHere)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Pair UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
if !unmarshalHere.Equal(configPair) {
|
||||
t.Errorf("Test Failed - Pairs UnmarshalJSON() error expected %s but received %s",
|
||||
configPair, unmarshalHere)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPairMarshalJSON(t *testing.T) {
|
||||
quickstruct := struct {
|
||||
Pair Pair `json:"superPair"`
|
||||
}{
|
||||
Pair{Base: BTC, Quote: USD, Delimiter: "-"},
|
||||
}
|
||||
|
||||
encoded, err := common.JSONEncode(quickstruct)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Pair MarshalJSON() error", err)
|
||||
}
|
||||
|
||||
expected := `{"superPair":"BTC-USD"}`
|
||||
if string(encoded) != expected {
|
||||
t.Errorf("Test Failed - Pair MarshalJSON() error expected %s but received %s",
|
||||
expected, string(encoded))
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCryptoPair(t *testing.T) {
|
||||
if !NewPair(BTC, LTC).IsCryptoPair() {
|
||||
t.Error("Test Failed. TestIsCryptoPair. Expected true result")
|
||||
}
|
||||
|
||||
if NewPair(BTC, USD).IsCryptoPair() {
|
||||
t.Error("Test Failed. TestIsCryptoPair. Expected false result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsCryptoFiatPair(t *testing.T) {
|
||||
if !NewPair(BTC, USD).IsCryptoFiatPair() {
|
||||
t.Error("Test Failed. TestIsCryptoPair. Expected true result")
|
||||
}
|
||||
|
||||
if NewPair(BTC, LTC).IsCryptoFiatPair() {
|
||||
t.Error("Test Failed. TestIsCryptoPair. Expected false result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsFiatPair(t *testing.T) {
|
||||
if !NewPair(AUD, USD).IsFiatPair() {
|
||||
t.Error("Test Failed. TestIsFiatPair. Expected true result")
|
||||
}
|
||||
|
||||
if NewPair(BTC, AUD).IsFiatPair() {
|
||||
t.Error("Test Failed. TestIsFiatPair. Expected false result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPair(BTC, USD)
|
||||
actual := defaultPair
|
||||
expected := pair.String()
|
||||
if actual != expected {
|
||||
t.Errorf("Test failed. String(): %s was not equal to expected value: %s",
|
||||
actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFirstCurrency(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPair(BTC, USD)
|
||||
actual := pair.Base
|
||||
expected := BTC
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. GetFirstCurrency(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecondCurrency(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPair(BTC, USD)
|
||||
actual := pair.Quote
|
||||
expected := USD
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. GetSecondCurrency(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPair(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPair(BTC, USD)
|
||||
actual := pair.String()
|
||||
expected := defaultPair
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisplay(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPairDelimiter(defaultPairWDelimiter, "-")
|
||||
actual := pair.String()
|
||||
expected := defaultPairWDelimiter
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
actual = pair.Format("", false).String()
|
||||
expected = "btcusd"
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
actual = pair.Format("~", true).String()
|
||||
expected = "BTC~USD"
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEquall(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPair(BTC, USD)
|
||||
secondPair := NewPair(BTC, USD)
|
||||
actual := pair.Equal(secondPair)
|
||||
expected := true
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Equal(): %v was not equal to expected value: %v",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
secondPair.Quote = ETH
|
||||
actual = pair.Equal(secondPair)
|
||||
expected = false
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Equal(): %v was not equal to expected value: %v",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
secondPair = NewPair(USD, BTC)
|
||||
actual = pair.Equal(secondPair)
|
||||
expected = false
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Equal(): %v was not equal to expected value: %v",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEqualIncludeReciprocal(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPair(BTC, USD)
|
||||
secondPair := NewPair(BTC, USD)
|
||||
actual := pair.EqualIncludeReciprocal(secondPair)
|
||||
expected := true
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Equal(): %v was not equal to expected value: %v",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
secondPair.Quote = ETH
|
||||
actual = pair.EqualIncludeReciprocal(secondPair)
|
||||
expected = false
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Equal(): %v was not equal to expected value: %v",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
secondPair = NewPair(USD, BTC)
|
||||
actual = pair.EqualIncludeReciprocal(secondPair)
|
||||
expected = true
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Equal(): %v was not equal to expected value: %v",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwap(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPair(BTC, USD)
|
||||
actual := pair.Swap().String()
|
||||
expected := "USDBTC"
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. TestSwap: %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPair(BTC, USD)
|
||||
if pair.IsEmpty() {
|
||||
t.Error("Test failed. Empty() returned true when the pair was initialised")
|
||||
}
|
||||
|
||||
p := NewPair(NewCode(""), NewCode(""))
|
||||
if !p.IsEmpty() {
|
||||
t.Error("Test failed. Empty() returned true when the pair wasn't initialised")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPair(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPair(BTC, USD)
|
||||
actual := pair.String()
|
||||
expected := defaultPair
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPairWithDelimiter(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPairWithDelimiter("BTC", "USD", "-test-")
|
||||
actual := pair.String()
|
||||
expected := "BTC-test-USD"
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
pair = NewPairWithDelimiter("BTC", "USD", "")
|
||||
actual = pair.String()
|
||||
expected = defaultPair
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPairDelimiter(t *testing.T) {
|
||||
t.Parallel()
|
||||
pair := NewPairDelimiter(defaultPairWDelimiter, "-")
|
||||
actual := pair.String()
|
||||
expected := defaultPairWDelimiter
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
actual = pair.Delimiter
|
||||
expected = "-"
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Delmiter: %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// TestNewPairFromIndex returns a CurrencyPair via a currency string and
|
||||
// specific index
|
||||
func TestNewPairFromIndex(t *testing.T) {
|
||||
t.Parallel()
|
||||
currency := defaultPair
|
||||
index := "BTC"
|
||||
|
||||
pair, err := NewPairFromIndex(currency, index)
|
||||
if err != nil {
|
||||
t.Error("test failed - NewPairFromIndex() error", err)
|
||||
}
|
||||
|
||||
pair.Delimiter = "-"
|
||||
actual := pair.String()
|
||||
|
||||
expected := defaultPairWDelimiter
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
currency = "DOGEBTC"
|
||||
|
||||
pair, err = NewPairFromIndex(currency, index)
|
||||
if err != nil {
|
||||
t.Error("test failed - NewPairFromIndex() error", err)
|
||||
}
|
||||
|
||||
pair.Delimiter = "-"
|
||||
actual = pair.String()
|
||||
|
||||
expected = "DOGE-BTC"
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPairFromString(t *testing.T) {
|
||||
t.Parallel()
|
||||
pairStr := defaultPairWDelimiter
|
||||
pair := NewPairFromString(pairStr)
|
||||
actual := pair.String()
|
||||
expected := defaultPairWDelimiter
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
|
||||
pairStr = defaultPair
|
||||
pair = NewPairFromString(pairStr)
|
||||
actual = pair.String()
|
||||
expected = defaultPair
|
||||
if actual != expected {
|
||||
t.Errorf(
|
||||
"Test failed. Pair(): %s was not equal to expected value: %s",
|
||||
actual, expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsCurrency(t *testing.T) {
|
||||
p := NewPair(BTC, USD)
|
||||
|
||||
if !p.ContainsCurrency(BTC) {
|
||||
t.Error("Test failed. TestContainsCurrency: Expected currency was not found")
|
||||
}
|
||||
|
||||
if p.ContainsCurrency(ETH) {
|
||||
t.Error("Test failed. TestContainsCurrency: Non-existent currency was found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatPairs(t *testing.T) {
|
||||
newP, err := FormatPairs([]string{""}, "-", "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - FormatPairs() error", err)
|
||||
}
|
||||
|
||||
if len(newP) > 0 {
|
||||
t.Error("Test failed. TestFormatPairs: Empty string returned a valid pair")
|
||||
}
|
||||
|
||||
newP, err = FormatPairs([]string{defaultPairWDelimiter}, "-", "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - FormatPairs() error", err)
|
||||
}
|
||||
|
||||
if newP[0].String() != defaultPairWDelimiter {
|
||||
t.Error("Test failed. TestFormatPairs: Expected pair was not found")
|
||||
}
|
||||
|
||||
newP, err = FormatPairs([]string{defaultPair}, "", "BTC")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - FormatPairs() error", err)
|
||||
}
|
||||
|
||||
if newP[0].String() != defaultPair {
|
||||
t.Error("Test failed. TestFormatPairs: Expected pair was not found")
|
||||
}
|
||||
newP, err = FormatPairs([]string{"ETHUSD"}, "", "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - FormatPairs() error", err)
|
||||
}
|
||||
|
||||
if newP[0].String() != "ETHUSD" {
|
||||
t.Error("Test failed. TestFormatPairs: Expected pair was not found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCopyPairFormat(t *testing.T) {
|
||||
pairOne := NewPair(BTC, USD)
|
||||
pairOne.Delimiter = "-"
|
||||
|
||||
var pairs []Pair
|
||||
pairs = append(pairs, pairOne, NewPair(LTC, USD))
|
||||
|
||||
testPair := NewPair(BTC, USD)
|
||||
testPair.Delimiter = "~"
|
||||
|
||||
result := CopyPairFormat(testPair, pairs, false)
|
||||
if result.String() != defaultPairWDelimiter {
|
||||
t.Error("Test failed. TestCopyPairFormat: Expected pair was not found")
|
||||
}
|
||||
|
||||
result = CopyPairFormat(NewPair(ETH, USD), pairs, true)
|
||||
if result.String() != "" {
|
||||
t.Error("Test failed. TestCopyPairFormat: Unexpected non empty pair returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindPairDifferences(t *testing.T) {
|
||||
pairList := NewPairsFromStrings([]string{defaultPairWDelimiter, "ETH-USD", "LTC-USD"})
|
||||
|
||||
// Test new pair update
|
||||
newPairs, removedPairs := pairList.FindDifferences(NewPairsFromStrings([]string{"DASH-USD"}))
|
||||
if len(newPairs) != 1 && len(removedPairs) != 3 {
|
||||
t.Error("Test failed. TestFindPairDifferences: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that we don't allow empty strings for new pairs
|
||||
newPairs, removedPairs = pairList.FindDifferences(NewPairsFromStrings([]string{""}))
|
||||
if len(newPairs) != 0 && len(removedPairs) != 3 {
|
||||
t.Error("Test failed. TestFindPairDifferences: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that we don't allow empty strings for new pairs
|
||||
newPairs, removedPairs = NewPairsFromStrings([]string{""}).FindDifferences(pairList)
|
||||
if len(newPairs) != 3 && len(removedPairs) != 0 {
|
||||
t.Error("Test failed. TestFindPairDifferences: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that the supplied pair lists are the same, so
|
||||
// no newPairs or removedPairs
|
||||
newPairs, removedPairs = pairList.FindDifferences(pairList)
|
||||
if len(newPairs) != 0 && len(removedPairs) != 0 {
|
||||
t.Error("Test failed. TestFindPairDifferences: Unexpected values")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPairsToStringArray(t *testing.T) {
|
||||
var pairs Pairs
|
||||
pairs = append(pairs, NewPair(BTC, USD))
|
||||
|
||||
expected := []string{defaultPair}
|
||||
actual := pairs.Strings()
|
||||
|
||||
if actual[0] != expected[0] {
|
||||
t.Error("Test failed. TestPairsToStringArray: Unexpected values")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandomPairFromPairs(t *testing.T) {
|
||||
// Test that an empty pairs array returns an empty currency pair
|
||||
var emptyPairs Pairs
|
||||
result := emptyPairs.GetRandomPair()
|
||||
if !result.IsEmpty() {
|
||||
t.Error("Test failed. TestRandomPairFromPairs: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that a populated pairs array returns a non-empty currency pair
|
||||
var pairs Pairs
|
||||
pairs = append(pairs, NewPair(BTC, USD))
|
||||
result = pairs.GetRandomPair()
|
||||
|
||||
if result.IsEmpty() {
|
||||
t.Error("Test failed. TestRandomPairFromPairs: Unexpected values")
|
||||
}
|
||||
|
||||
// Test that a populated pairs array over a number of attempts returns ALL
|
||||
// currency pairs
|
||||
pairs = append(pairs, NewPair(ETH, USD))
|
||||
expectedResults := make(map[string]bool)
|
||||
for i := 0; i < 50; i++ {
|
||||
p := pairs.GetRandomPair().String()
|
||||
_, ok := expectedResults[p]
|
||||
if !ok {
|
||||
expectedResults[p] = true
|
||||
}
|
||||
}
|
||||
|
||||
for x := range pairs {
|
||||
_, ok := expectedResults[pairs[x].String()]
|
||||
if !ok {
|
||||
t.Error("Test failed. TestRandomPairFromPairs: Unexpected values")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsInvalid(t *testing.T) {
|
||||
p := NewPair(LTC, LTC)
|
||||
if !p.IsInvalid() {
|
||||
t.Error("Test Failed - IsInvalid() error expect true but received false")
|
||||
}
|
||||
}
|
||||
158
currency/pairs.go
Normal file
158
currency/pairs.go
Normal file
@@ -0,0 +1,158 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
// NewPairsFromStrings takes in currency pair strings and returns a currency
|
||||
// pair list
|
||||
func NewPairsFromStrings(pairs []string) Pairs {
|
||||
var ps Pairs
|
||||
for _, p := range pairs {
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
ps = append(ps, NewPairFromString(p))
|
||||
}
|
||||
return ps
|
||||
}
|
||||
|
||||
// Pairs defines a list of pairs
|
||||
type Pairs []Pair
|
||||
|
||||
// Strings returns a slice of strings referring to each currency pair
|
||||
func (p Pairs) Strings() []string {
|
||||
var list []string
|
||||
for i := range p {
|
||||
list = append(list, p[i].String())
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// Join returns a comma separated list of currency pairs
|
||||
func (p Pairs) Join() string {
|
||||
return common.JoinStrings(p.Strings(), ",")
|
||||
}
|
||||
|
||||
// Format formats the pair list to the exchange format configuration
|
||||
func (p Pairs) Format(delimiter, index string, uppercase bool) Pairs {
|
||||
var pairs Pairs
|
||||
for i := range p {
|
||||
var formattedPair Pair
|
||||
formattedPair.Delimiter = delimiter
|
||||
formattedPair.Base = p[i].Base
|
||||
formattedPair.Quote = p[i].Quote
|
||||
|
||||
if index != "" {
|
||||
formattedPair.Quote = NewCode(index)
|
||||
}
|
||||
|
||||
if uppercase {
|
||||
pairs = append(pairs, formattedPair.Upper())
|
||||
} else {
|
||||
pairs = append(pairs, formattedPair)
|
||||
}
|
||||
}
|
||||
return pairs
|
||||
}
|
||||
|
||||
// UnmarshalJSON comforms type to the umarshaler interface
|
||||
func (p *Pairs) UnmarshalJSON(d []byte) error {
|
||||
var pairs string
|
||||
err := common.JSONDecode(d, &pairs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var allThePairs Pairs
|
||||
for _, data := range common.SplitStrings(pairs, ",") {
|
||||
allThePairs = append(allThePairs, NewPairFromString(data))
|
||||
}
|
||||
|
||||
*p = allThePairs
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON conforms type to the marshaler interface
|
||||
func (p Pairs) MarshalJSON() ([]byte, error) {
|
||||
return common.JSONEncode(p.Join())
|
||||
}
|
||||
|
||||
// Upper returns an upper formatted pair list
|
||||
func (p Pairs) Upper() Pairs {
|
||||
var upper Pairs
|
||||
for i := range p {
|
||||
upper = append(upper, p[i].Upper())
|
||||
}
|
||||
return upper
|
||||
}
|
||||
|
||||
// Slice exposes the underlying type
|
||||
func (p Pairs) Slice() []Pair {
|
||||
return p
|
||||
}
|
||||
|
||||
// Contains checks to see if a specified pair exists inside a currency pair
|
||||
// array
|
||||
func (p Pairs) Contains(check Pair, exact bool) bool {
|
||||
for _, pair := range p.Slice() {
|
||||
if exact {
|
||||
if pair.Equal(check) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if pair.EqualIncludeReciprocal(check) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RemovePairsByFilter checks to see if a pair contains a specific currency
|
||||
// and removes it from the list of pairs
|
||||
func (p Pairs) RemovePairsByFilter(filter Code) Pairs {
|
||||
var pairs Pairs
|
||||
for _, pair := range p.Slice() {
|
||||
if pair.ContainsCurrency(filter) {
|
||||
continue
|
||||
}
|
||||
pairs = append(pairs, pair)
|
||||
}
|
||||
return pairs
|
||||
}
|
||||
|
||||
// FindDifferences returns pairs which are new or have been removed
|
||||
func (p Pairs) FindDifferences(pairs Pairs) (newPairs, removedPairs Pairs) {
|
||||
for x := range pairs {
|
||||
if pairs[x].String() == "" {
|
||||
continue
|
||||
}
|
||||
if !p.Contains(pairs[x], true) {
|
||||
newPairs = append(newPairs, pairs[x])
|
||||
}
|
||||
}
|
||||
for _, oldPair := range p {
|
||||
if oldPair.String() == "" {
|
||||
continue
|
||||
}
|
||||
if !pairs.Contains(oldPair, true) {
|
||||
removedPairs = append(removedPairs, oldPair)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetRandomPair returns a random pair from a list of pairs
|
||||
func (p Pairs) GetRandomPair() Pair {
|
||||
pairsLen := len(p)
|
||||
|
||||
if pairsLen == 0 {
|
||||
return Pair{Base: NewCode(""), Quote: NewCode("")}
|
||||
}
|
||||
|
||||
return p[rand.Intn(pairsLen)]
|
||||
}
|
||||
133
currency/pairs_test.go
Normal file
133
currency/pairs_test.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
)
|
||||
|
||||
func TestPairsUpper(t *testing.T) {
|
||||
pairs := NewPairsFromStrings([]string{"btc_usd", "btc_aud", "btc_ltc"})
|
||||
expected := "BTC_USD,BTC_AUD,BTC_LTC"
|
||||
|
||||
if pairs.Upper().Join() != expected {
|
||||
t.Errorf("Test Failed - Pairs Join() error expected %s but received %s",
|
||||
expected, pairs.Join())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPairsString(t *testing.T) {
|
||||
pairs := NewPairsFromStrings([]string{"btc_usd", "btc_aud", "btc_ltc"})
|
||||
expected := []string{"btc_usd", "btc_aud", "btc_ltc"}
|
||||
|
||||
for i, p := range pairs {
|
||||
if p.String() != expected[i] {
|
||||
t.Errorf("Test Failed - Pairs String() error expected %s but received %s",
|
||||
expected, p.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPairsJoin(t *testing.T) {
|
||||
pairs := NewPairsFromStrings([]string{"btc_usd", "btc_aud", "btc_ltc"})
|
||||
expected := "btc_usd,btc_aud,btc_ltc"
|
||||
|
||||
if pairs.Join() != expected {
|
||||
t.Errorf("Test Failed - Pairs Join() error expected %s but received %s",
|
||||
expected, pairs.Join())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPairsFormat(t *testing.T) {
|
||||
pairs := NewPairsFromStrings([]string{"btc_usd", "btc_aud", "btc_ltc"})
|
||||
|
||||
expected := "BTC-USD,BTC-AUD,BTC-LTC"
|
||||
if pairs.Format("-", "", true).Join() != expected {
|
||||
t.Errorf("Test Failed - Pairs Join() error expected %s but received %s",
|
||||
expected, pairs.Format("-", "", true).Join())
|
||||
}
|
||||
|
||||
expected = "btc:usd,btc:aud,btc:ltc"
|
||||
if pairs.Format(":", "", false).Join() != expected {
|
||||
t.Errorf("Test Failed - Pairs Join() error expected %s but received %s",
|
||||
expected, pairs.Format("-", "", true).Join())
|
||||
}
|
||||
|
||||
expected = "btc:krw,btc:krw,btc:krw"
|
||||
if pairs.Format(":", "krw", false).Join() != expected {
|
||||
t.Errorf("Test Failed - Pairs Join() error expected %s but received %s",
|
||||
expected, pairs.Format("-", "", true).Join())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPairsUnmarshalJSON(t *testing.T) {
|
||||
var unmarshalHere Pairs
|
||||
configPairs := "btc_usd,btc_aud,btc_ltc"
|
||||
|
||||
encoded, err := common.JSONEncode(configPairs)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Pairs UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
err = common.JSONDecode(encoded, &unmarshalHere)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Pairs UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
err = common.JSONDecode(encoded, &unmarshalHere)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Pairs UnmarshalJSON() error", err)
|
||||
}
|
||||
|
||||
if unmarshalHere.Join() != configPairs {
|
||||
t.Errorf("Test Failed - Pairs UnmarshalJSON() error expected %s but received %s",
|
||||
configPairs, unmarshalHere.Join())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPairsMarshalJSON(t *testing.T) {
|
||||
quickstruct := struct {
|
||||
Pairs Pairs `json:"soManyPairs"`
|
||||
}{
|
||||
Pairs: NewPairsFromStrings([]string{"btc_usd", "btc_aud", "btc_ltc"}),
|
||||
}
|
||||
|
||||
encoded, err := common.JSONEncode(quickstruct)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Pairs MarshalJSON() error", err)
|
||||
}
|
||||
|
||||
expected := `{"soManyPairs":"btc_usd,btc_aud,btc_ltc"}`
|
||||
if string(encoded) != expected {
|
||||
t.Errorf("Test Failed - Pairs MarshalJSON() error expected %s but received %s",
|
||||
expected, string(encoded))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemovePairsByFilter(t *testing.T) {
|
||||
var pairs = Pairs{
|
||||
NewPair(BTC, USD),
|
||||
NewPair(LTC, USD),
|
||||
NewPair(LTC, USDT),
|
||||
}
|
||||
|
||||
pairs = pairs.RemovePairsByFilter(USDT)
|
||||
if pairs.Contains(NewPair(LTC, USDT), true) {
|
||||
t.Error("Test failed. TestRemovePairsByFilter unexpected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContains(t *testing.T) {
|
||||
var pairs = Pairs{
|
||||
NewPair(BTC, USD),
|
||||
NewPair(LTC, USD),
|
||||
}
|
||||
|
||||
if !pairs.Contains(NewPair(BTC, USD), true) {
|
||||
t.Errorf("Test failed. TestContains: Expected pair was not found")
|
||||
}
|
||||
|
||||
if pairs.Contains(NewPair(ETH, USD), false) {
|
||||
t.Errorf("Test failed. TestContains: Non-existent pair was found")
|
||||
}
|
||||
}
|
||||
754
currency/storage.go
Normal file
754
currency/storage.go
Normal file
@@ -0,0 +1,754 @@
|
||||
package currency
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/coinmarketcap"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider/base"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
// CurrencyFileUpdateDelay defines the rate at which the currency.json file is
|
||||
// updated
|
||||
const (
|
||||
DefaultCurrencyFileDelay = 168 * time.Hour
|
||||
DefaultForeignExchangeDelay = 1 * time.Minute
|
||||
)
|
||||
|
||||
func init() {
|
||||
storage.SetDefaults()
|
||||
}
|
||||
|
||||
// storage is an overarching type that keeps track of and updates currency,
|
||||
// currency exchange rates and pairs
|
||||
var storage Storage
|
||||
|
||||
// Storage contains the loaded storage currencies supported on available crypto
|
||||
// or fiat marketplaces
|
||||
// NOTE: All internal currencies are upper case
|
||||
type Storage struct {
|
||||
// FiatCurrencies defines the running fiat currencies in the currency
|
||||
// storage
|
||||
fiatCurrencies Currencies
|
||||
|
||||
// Cryptocurrencies defines the running cryptocurrencies in the currency
|
||||
// storage
|
||||
cryptocurrencies Currencies
|
||||
|
||||
// CurrencyCodes is a full basket of currencies either crypto, fiat, ico or
|
||||
// contract being tracked by the currency storage system
|
||||
currencyCodes BaseCodes
|
||||
|
||||
// Main converting currency
|
||||
baseCurrency Code
|
||||
|
||||
// FXRates defines a protected conversion rate map
|
||||
fxRates ConversionRates
|
||||
|
||||
// DefaultBaseCurrency is the base currency used for conversion
|
||||
defaultBaseCurrency Code
|
||||
|
||||
// DefaultFiatCurrencies has the default minimum of FIAT values
|
||||
defaultFiatCurrencies Currencies
|
||||
|
||||
// DefaultCryptoCurrencies has the default minimum of crytpocurrency values
|
||||
defaultCryptoCurrencies Currencies
|
||||
|
||||
// FiatExchangeMarkets defines an interface to access FX data for fiat
|
||||
// currency rates
|
||||
fiatExchangeMarkets *forexprovider.ForexProviders
|
||||
|
||||
// CurrencyAnalysis defines a full market analysis suite to receieve and
|
||||
// define different fiat currencies, cryptocurrencies and markets
|
||||
currencyAnalysis *coinmarketcap.Coinmarketcap
|
||||
|
||||
// Path defines the main folder to dump and find currency JSON
|
||||
path string
|
||||
|
||||
// Update delay variables
|
||||
currencyFileUpdateDelay time.Duration
|
||||
foreignExchangeUpdateDelay time.Duration
|
||||
|
||||
mtx sync.Mutex
|
||||
wg sync.WaitGroup
|
||||
shutdownC chan struct{}
|
||||
updaterRunning bool
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
// SetDefaults sets storage defaults for basic package functionality
|
||||
func (s *Storage) SetDefaults() {
|
||||
s.defaultBaseCurrency = USD
|
||||
s.baseCurrency = s.defaultBaseCurrency
|
||||
s.SetDefaultFiatCurrencies(USD, AUD, EUR, CNY)
|
||||
s.SetDefaultCryptocurrencies(BTC, LTC, ETH, DOGE, DASH, XRP, XMR)
|
||||
s.SetupConversionRates()
|
||||
s.fiatExchangeMarkets = forexprovider.NewDefaultFXProvider()
|
||||
}
|
||||
|
||||
// RunUpdater runs the foreign exchange updater service. This will set up a JSON
|
||||
// dump file and keep foreign exchange rates updated as fast as possible without
|
||||
// triggering rate limiters, it will also run a full cryptocurrency check
|
||||
// through coin market cap and expose analytics for exchange services
|
||||
func (s *Storage) RunUpdater(overrides BotOverrides, settings MainConfiguration, filePath string, verbose bool) error {
|
||||
s.mtx.Lock()
|
||||
|
||||
if !settings.Cryptocurrencies.HasData() {
|
||||
s.mtx.Unlock()
|
||||
return errors.New("currency storage error, no cryptocurrencies loaded")
|
||||
}
|
||||
s.cryptocurrencies = settings.Cryptocurrencies
|
||||
|
||||
if settings.FiatDisplayCurrency.IsEmpty() {
|
||||
s.mtx.Unlock()
|
||||
return errors.New("currency storage error, no fiat display currency set in config")
|
||||
}
|
||||
s.baseCurrency = settings.FiatDisplayCurrency
|
||||
log.Debugf("Fiat display currency: %s.", s.baseCurrency)
|
||||
|
||||
if settings.CryptocurrencyProvider.Enabled {
|
||||
log.Debugf("Setting up currency analysis system with Coinmarketcap...")
|
||||
c := &coinmarketcap.Coinmarketcap{}
|
||||
c.SetDefaults()
|
||||
c.Setup(coinmarketcap.Settings{
|
||||
Name: settings.CryptocurrencyProvider.Name,
|
||||
Enabled: true,
|
||||
AccountPlan: settings.CryptocurrencyProvider.AccountPlan,
|
||||
APIkey: settings.CryptocurrencyProvider.APIkey,
|
||||
Verbose: settings.CryptocurrencyProvider.Verbose,
|
||||
})
|
||||
|
||||
s.currencyAnalysis = c
|
||||
}
|
||||
|
||||
if filePath == "" {
|
||||
s.mtx.Unlock()
|
||||
return errors.New("currency package runUpdater error filepath not set")
|
||||
}
|
||||
|
||||
s.path = filePath + common.GetOSPathSlash() + "currency.json"
|
||||
|
||||
if settings.CurrencyDelay.Nanoseconds() == 0 {
|
||||
s.currencyFileUpdateDelay = DefaultCurrencyFileDelay
|
||||
} else {
|
||||
s.currencyFileUpdateDelay = settings.CurrencyDelay
|
||||
}
|
||||
|
||||
if settings.FxRateDelay.Nanoseconds() == 0 {
|
||||
s.foreignExchangeUpdateDelay = DefaultForeignExchangeDelay
|
||||
} else {
|
||||
s.foreignExchangeUpdateDelay = settings.FxRateDelay
|
||||
}
|
||||
|
||||
var fxSettings []base.Settings
|
||||
for i := range settings.ForexProviders {
|
||||
switch settings.ForexProviders[i].Name {
|
||||
case "CurrencyConverter":
|
||||
if overrides.FxCurrencyConverter ||
|
||||
settings.ForexProviders[i].Enabled {
|
||||
settings.ForexProviders[i].Enabled = true
|
||||
fxSettings = append(fxSettings,
|
||||
base.Settings(settings.ForexProviders[i]))
|
||||
}
|
||||
|
||||
case "CurrencyLayer":
|
||||
if overrides.FxCurrencyLayer || settings.ForexProviders[i].Enabled {
|
||||
settings.ForexProviders[i].Enabled = true
|
||||
fxSettings = append(fxSettings,
|
||||
base.Settings(settings.ForexProviders[i]))
|
||||
}
|
||||
|
||||
case "Fixer":
|
||||
if overrides.FxFixer || settings.ForexProviders[i].Enabled {
|
||||
settings.ForexProviders[i].Enabled = true
|
||||
fxSettings = append(fxSettings,
|
||||
base.Settings(settings.ForexProviders[i]))
|
||||
}
|
||||
|
||||
case "OpenExchangeRates":
|
||||
if overrides.FxOpenExchangeRates ||
|
||||
settings.ForexProviders[i].Enabled {
|
||||
settings.ForexProviders[i].Enabled = true
|
||||
fxSettings = append(fxSettings,
|
||||
base.Settings(settings.ForexProviders[i]))
|
||||
}
|
||||
|
||||
case "ExchangeRates":
|
||||
// TODO ADD OVERRIDE
|
||||
if settings.ForexProviders[i].Enabled {
|
||||
settings.ForexProviders[i].Enabled = true
|
||||
fxSettings = append(fxSettings,
|
||||
base.Settings(settings.ForexProviders[i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(fxSettings) != 0 {
|
||||
var err error
|
||||
s.fiatExchangeMarkets, err = forexprovider.StartFXService(fxSettings)
|
||||
if err != nil {
|
||||
s.mtx.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("Primary foreign exchange conversion provider %s enabled",
|
||||
s.fiatExchangeMarkets.Primary.Provider.GetName())
|
||||
|
||||
for i := range s.fiatExchangeMarkets.Support {
|
||||
log.Debugf("Support forex conversion provider %s enabled",
|
||||
s.fiatExchangeMarkets.Support[i].Provider.GetName())
|
||||
}
|
||||
|
||||
// Mutex present in this go routine to lock down retrieving rate data
|
||||
// until this system initially updates
|
||||
go s.ForeignExchangeUpdater()
|
||||
} else {
|
||||
log.Warnf("No foreign exchange providers enabled in config.json")
|
||||
s.mtx.Unlock()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupConversionRates sets default conversion rate values
|
||||
func (s *Storage) SetupConversionRates() {
|
||||
s.fxRates = ConversionRates{
|
||||
m: make(map[*Item]map[*Item]*float64),
|
||||
}
|
||||
}
|
||||
|
||||
// SetDefaultFiatCurrencies assigns the default fiat currency list and adds it
|
||||
// to the running list
|
||||
func (s *Storage) SetDefaultFiatCurrencies(c ...Code) {
|
||||
for _, currency := range c {
|
||||
s.defaultFiatCurrencies = append(s.defaultFiatCurrencies, currency)
|
||||
s.fiatCurrencies = append(s.fiatCurrencies, currency)
|
||||
}
|
||||
}
|
||||
|
||||
// SetDefaultCryptocurrencies assigns the default cryptocurrency list and adds
|
||||
// it to the running list
|
||||
func (s *Storage) SetDefaultCryptocurrencies(c ...Code) {
|
||||
for _, currency := range c {
|
||||
s.defaultCryptoCurrencies = append(s.defaultCryptoCurrencies, currency)
|
||||
s.cryptocurrencies = append(s.cryptocurrencies, currency)
|
||||
}
|
||||
}
|
||||
|
||||
// SetupForexProviders sets up a new instance of the forex providers
|
||||
func (s *Storage) SetupForexProviders(setting ...base.Settings) error {
|
||||
addr, err := forexprovider.StartFXService(setting)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.fiatExchangeMarkets = addr
|
||||
return nil
|
||||
}
|
||||
|
||||
// ForeignExchangeUpdater is a routine that seeds foreign exchange rate and keeps
|
||||
// updated as fast as possible
|
||||
func (s *Storage) ForeignExchangeUpdater() {
|
||||
log.Debugf("Foreign exchange updater started, seeding FX rate list..")
|
||||
|
||||
s.wg.Add(1)
|
||||
defer s.wg.Done()
|
||||
|
||||
err := s.SeedCurrencyAnalysisData()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
err = s.SeedForeignExchangeRates()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
// Unlock main rate retrieval mutex so all routines waiting can get access
|
||||
// to data
|
||||
s.mtx.Unlock()
|
||||
|
||||
// Set tickers to client defined rates or defaults
|
||||
SeedForeignExchangeTick := time.NewTicker(s.foreignExchangeUpdateDelay)
|
||||
SeedCurrencyAnalysisTick := time.NewTicker(s.currencyFileUpdateDelay)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.shutdownC:
|
||||
return
|
||||
|
||||
case <-SeedForeignExchangeTick.C:
|
||||
err := s.SeedForeignExchangeRates()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
case <-SeedCurrencyAnalysisTick.C:
|
||||
err := s.SeedCurrencyAnalysisData()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SeedCurrencyAnalysisData sets a new instance of a coinmarketcap data.
|
||||
func (s *Storage) SeedCurrencyAnalysisData() error {
|
||||
b, err := common.ReadFile(s.path)
|
||||
if err != nil {
|
||||
err = s.FetchCurrencyAnalysisData()
|
||||
if err != nil {
|
||||
return s.WriteCurrencyDataToFile(s.path, false)
|
||||
}
|
||||
|
||||
return s.WriteCurrencyDataToFile(s.path, true)
|
||||
}
|
||||
|
||||
var fromFile File
|
||||
err = common.JSONDecode(b, &fromFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.LoadFileCurrencyData(fromFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Based on update delay update the file
|
||||
if fromFile.LastMainUpdate.After(fromFile.LastMainUpdate.Add(s.currencyFileUpdateDelay)) ||
|
||||
fromFile.LastMainUpdate.IsZero() {
|
||||
err = s.FetchCurrencyAnalysisData()
|
||||
if err != nil {
|
||||
return s.WriteCurrencyDataToFile(s.path, false)
|
||||
}
|
||||
|
||||
return s.WriteCurrencyDataToFile(s.path, true)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FetchCurrencyAnalysisData fetches a new fresh batch of currency data and
|
||||
// loads it into memory
|
||||
func (s *Storage) FetchCurrencyAnalysisData() error {
|
||||
if s.currencyAnalysis == nil {
|
||||
log.Warn("Currency analysis system offline please set api keys for coinmarketcap")
|
||||
return errors.New("currency analysis system offline")
|
||||
}
|
||||
|
||||
return s.UpdateCurrencies()
|
||||
}
|
||||
|
||||
// WriteCurrencyDataToFile writes the full currency data to a designated file
|
||||
func (s *Storage) WriteCurrencyDataToFile(path string, mainUpdate bool) error {
|
||||
data, err := s.currencyCodes.GetFullCurrencyData()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mainUpdate {
|
||||
t := time.Now()
|
||||
data.LastMainUpdate = t
|
||||
s.currencyCodes.LastMainUpdate = t
|
||||
}
|
||||
|
||||
var encoded []byte
|
||||
encoded, err = json.MarshalIndent(data, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return common.WriteFile(path, encoded)
|
||||
}
|
||||
|
||||
// LoadFileCurrencyData loads currencies into the currency codes
|
||||
func (s *Storage) LoadFileCurrencyData(f File) error {
|
||||
for _, contract := range f.Contracts {
|
||||
err := s.currencyCodes.LoadItem(contract)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, crypto := range f.Cryptocurrency {
|
||||
err := s.currencyCodes.LoadItem(crypto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, fiat := range f.FiatCurrency {
|
||||
err := s.currencyCodes.LoadItem(fiat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, token := range f.Token {
|
||||
err := s.currencyCodes.LoadItem(token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, unset := range f.UnsetCurrency {
|
||||
err := s.currencyCodes.LoadItem(unset)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
s.currencyCodes.LastMainUpdate = f.LastMainUpdate
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCurrencies updates currency roll and information using coin market cap
|
||||
func (s *Storage) UpdateCurrencies() error {
|
||||
m, err := s.currencyAnalysis.GetCryptocurrencyIDMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for x := range m {
|
||||
if m[x].IsActive != 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
if m[x].Platform.Symbol != "" {
|
||||
err := s.currencyCodes.UpdateToken(m[x].Name,
|
||||
m[x].Symbol,
|
||||
m[x].Platform.Symbol,
|
||||
m[x].ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
err := s.currencyCodes.UpdateCryptocurrency(m[x].Name,
|
||||
m[x].Symbol,
|
||||
m[x].ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SeedForeignExchangeRatesByCurrencies seeds the foreign exchange rates by
|
||||
// currencies supplied
|
||||
func (s *Storage) SeedForeignExchangeRatesByCurrencies(c Currencies) error {
|
||||
s.fxRates.mtx.Lock()
|
||||
defer s.fxRates.mtx.Unlock()
|
||||
rates, err := s.fiatExchangeMarkets.GetCurrencyData(s.baseCurrency.String(),
|
||||
c.Strings())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.updateExchangeRates(rates)
|
||||
}
|
||||
|
||||
// SeedForeignExchangeRate returns a singular exchange rate
|
||||
func (s *Storage) SeedForeignExchangeRate(from, to Code) (map[string]float64, error) {
|
||||
return s.fiatExchangeMarkets.GetCurrencyData(from.String(),
|
||||
[]string{to.String()})
|
||||
}
|
||||
|
||||
// GetDefaultForeignExchangeRates returns foreign exchange rates based off
|
||||
// default fiat currencies.
|
||||
func (s *Storage) GetDefaultForeignExchangeRates() (Conversions, error) {
|
||||
if !s.updaterRunning {
|
||||
err := s.SeedDefaultForeignExchangeRates()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return s.fxRates.GetFullRates(), nil
|
||||
}
|
||||
|
||||
// SeedDefaultForeignExchangeRates seeds the default foreign exchange rates
|
||||
func (s *Storage) SeedDefaultForeignExchangeRates() error {
|
||||
s.fxRates.mtx.Lock()
|
||||
defer s.fxRates.mtx.Unlock()
|
||||
rates, err := s.fiatExchangeMarkets.GetCurrencyData(
|
||||
s.defaultBaseCurrency.String(),
|
||||
s.defaultFiatCurrencies.Strings())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.updateExchangeRates(rates)
|
||||
}
|
||||
|
||||
// GetExchangeRates returns storage seeded exchange rates
|
||||
func (s *Storage) GetExchangeRates() (Conversions, error) {
|
||||
if !s.updaterRunning {
|
||||
err := s.SeedForeignExchangeRates()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return s.fxRates.GetFullRates(), nil
|
||||
}
|
||||
|
||||
// SeedForeignExchangeRates seeds the foreign exchange rates from storage config
|
||||
// currencies
|
||||
func (s *Storage) SeedForeignExchangeRates() error {
|
||||
s.fxRates.mtx.Lock()
|
||||
defer s.fxRates.mtx.Unlock()
|
||||
rates, err := s.fiatExchangeMarkets.GetCurrencyData(
|
||||
s.baseCurrency.String(),
|
||||
s.fiatCurrencies.Strings())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.updateExchangeRates(rates)
|
||||
}
|
||||
|
||||
// UpdateForeignExchangeRates sets exchange rates on the FX map
|
||||
func (s *Storage) updateExchangeRates(m map[string]float64) error {
|
||||
err := s.fxRates.Update(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if s.path != "" {
|
||||
return s.WriteCurrencyDataToFile(s.path, false)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupCryptoProvider sets congiguration parameters and starts a new instance
|
||||
// of the currency analyser
|
||||
func (s *Storage) SetupCryptoProvider(settings coinmarketcap.Settings) error {
|
||||
if settings.APIkey == "" ||
|
||||
settings.APIkey == "key" ||
|
||||
settings.AccountPlan == "" ||
|
||||
settings.AccountPlan == "accountPlan" {
|
||||
return errors.New("currencyprovider error api key or plan not set in config.json")
|
||||
}
|
||||
|
||||
s.currencyAnalysis = new(coinmarketcap.Coinmarketcap)
|
||||
s.currencyAnalysis.SetDefaults()
|
||||
s.currencyAnalysis.Setup(settings)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTotalMarketCryptocurrencies returns the total seeded market
|
||||
// cryptocurrencies
|
||||
func (s *Storage) GetTotalMarketCryptocurrencies() (Currencies, error) {
|
||||
if !s.currencyCodes.HasData() {
|
||||
return nil, errors.New("market currency codes not populated")
|
||||
}
|
||||
return s.currencyCodes.GetCurrencies(), nil
|
||||
}
|
||||
|
||||
// IsDefaultCurrency returns if a currency is a default currency
|
||||
func (s *Storage) IsDefaultCurrency(c Code) bool {
|
||||
t, _ := GetTranslation(c)
|
||||
for _, d := range s.defaultFiatCurrencies {
|
||||
if d.Match(c) || d.Match(t) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsDefaultCryptocurrency returns if a cryptocurrency is a default
|
||||
// cryptocurrency
|
||||
func (s *Storage) IsDefaultCryptocurrency(c Code) bool {
|
||||
t, _ := GetTranslation(c)
|
||||
for _, d := range s.defaultCryptoCurrencies {
|
||||
if d.Match(c) || d.Match(t) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsFiatCurrency returns if a currency is part of the enabled fiat currency
|
||||
// list
|
||||
func (s *Storage) IsFiatCurrency(c Code) bool {
|
||||
if c.Item.Role != Unset {
|
||||
return c.Item.Role == Fiat
|
||||
}
|
||||
|
||||
t, _ := GetTranslation(c)
|
||||
for _, d := range s.fiatCurrencies {
|
||||
if d.Match(c) || d.Match(t) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCryptocurrency returns if a cryptocurrency is part of the enabled
|
||||
// cryptocurrency list
|
||||
func (s *Storage) IsCryptocurrency(c Code) bool {
|
||||
if c.Item.Role != Unset {
|
||||
return c.Item.Role == Cryptocurrency
|
||||
}
|
||||
|
||||
t, _ := GetTranslation(c)
|
||||
for _, d := range s.cryptocurrencies {
|
||||
if d.Match(c) || d.Match(t) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidateCode validates string against currency list and returns a currency
|
||||
// code
|
||||
func (s *Storage) ValidateCode(newCode string) Code {
|
||||
return s.currencyCodes.Register(newCode)
|
||||
}
|
||||
|
||||
// ValidateFiatCode validates a fiat currency string and returns a currency
|
||||
// code
|
||||
func (s *Storage) ValidateFiatCode(newCode string) (Code, error) {
|
||||
c, err := s.currencyCodes.RegisterFiat(newCode)
|
||||
if err != nil {
|
||||
return c, err
|
||||
}
|
||||
if !s.fiatCurrencies.Contains(c) {
|
||||
s.fiatCurrencies = append(s.fiatCurrencies, c)
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ValidateCryptoCode validates a cryptocurrency string and returns a currency
|
||||
// code
|
||||
// TODO: Update and add in RegisterCrypto member func
|
||||
func (s *Storage) ValidateCryptoCode(newCode string) Code {
|
||||
c := s.currencyCodes.Register(newCode)
|
||||
if !s.cryptocurrencies.Contains(c) {
|
||||
s.cryptocurrencies = append(s.cryptocurrencies, c)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// UpdateBaseCurrency changes base currency
|
||||
func (s *Storage) UpdateBaseCurrency(c Code) error {
|
||||
if c.IsFiatCurrency() {
|
||||
s.baseCurrency = c
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("currency %s not fiat failed to set currency", c)
|
||||
}
|
||||
|
||||
// GetCryptocurrencies returns the cryptocurrency list
|
||||
func (s *Storage) GetCryptocurrencies() Currencies {
|
||||
return s.cryptocurrencies
|
||||
}
|
||||
|
||||
// GetDefaultCryptocurrencies returns a list of default cryptocurrencies
|
||||
func (s *Storage) GetDefaultCryptocurrencies() Currencies {
|
||||
return s.defaultCryptoCurrencies
|
||||
}
|
||||
|
||||
// GetFiatCurrencies returns the fiat currencies list
|
||||
func (s *Storage) GetFiatCurrencies() Currencies {
|
||||
return s.fiatCurrencies
|
||||
}
|
||||
|
||||
// GetDefaultFiatCurrencies returns the default fiat currencies list
|
||||
func (s *Storage) GetDefaultFiatCurrencies() Currencies {
|
||||
return s.defaultFiatCurrencies
|
||||
}
|
||||
|
||||
// GetDefaultBaseCurrency returns the default base currency
|
||||
func (s *Storage) GetDefaultBaseCurrency() Code {
|
||||
return s.defaultBaseCurrency
|
||||
}
|
||||
|
||||
// GetBaseCurrency returns the current storage base currency
|
||||
func (s *Storage) GetBaseCurrency() Code {
|
||||
return s.baseCurrency
|
||||
}
|
||||
|
||||
// UpdateEnabledCryptoCurrencies appends new cryptocurrencies to the enabled
|
||||
// currency list
|
||||
func (s *Storage) UpdateEnabledCryptoCurrencies(c Currencies) {
|
||||
for _, i := range c {
|
||||
if !s.cryptocurrencies.Contains(i) {
|
||||
s.cryptocurrencies = append(s.cryptocurrencies, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateEnabledFiatCurrencies appends new fiat currencies to the enabled
|
||||
// currency list
|
||||
func (s *Storage) UpdateEnabledFiatCurrencies(c Currencies) {
|
||||
for _, i := range c {
|
||||
if !s.fiatCurrencies.Contains(i) && !s.cryptocurrencies.Contains(i) {
|
||||
s.fiatCurrencies = append(s.fiatCurrencies, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertCurrency for example converts $1 USD to the equivalent Japanese Yen
|
||||
// or vice versa.
|
||||
func (s *Storage) ConvertCurrency(amount float64, from, to Code) (float64, error) {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
if !s.fxRates.HasData() {
|
||||
err := s.SeedDefaultForeignExchangeRates()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
r, err := s.fxRates.GetRate(from, to)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return r * amount, nil
|
||||
}
|
||||
|
||||
// GetStorageRate returns the rate of the conversion value
|
||||
func (s *Storage) GetStorageRate(from, to Code) (float64, error) {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
if !s.fxRates.HasData() {
|
||||
err := s.SeedDefaultForeignExchangeRates()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
return s.fxRates.GetRate(from, to)
|
||||
}
|
||||
|
||||
// NewConversion returns a new conversion object that has a pointer to a related
|
||||
// rate with its inversion.
|
||||
func (s *Storage) NewConversion(from, to Code) (Conversion, error) {
|
||||
s.mtx.Lock()
|
||||
defer s.mtx.Unlock()
|
||||
|
||||
if !s.fxRates.HasData() {
|
||||
err := storage.SeedDefaultForeignExchangeRates()
|
||||
if err != nil {
|
||||
return Conversion{}, err
|
||||
}
|
||||
}
|
||||
return s.fxRates.Register(from, to)
|
||||
}
|
||||
|
||||
// IsVerbose returns if the storage is in verbose mode
|
||||
func (s *Storage) IsVerbose() bool {
|
||||
return s.Verbose
|
||||
}
|
||||
27
currency/storage_test.go
Normal file
27
currency/storage_test.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package currency
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestRunUpdater(t *testing.T) {
|
||||
var newStorage Storage
|
||||
|
||||
err := newStorage.RunUpdater(BotOverrides{}, MainConfiguration{}, "", false)
|
||||
if err == nil {
|
||||
t.Fatal("Test Failed storage RunUpdater() error cannot be nil")
|
||||
}
|
||||
|
||||
mainConfig := MainConfiguration{
|
||||
Cryptocurrencies: NewCurrenciesFromStringArray([]string{"BTC"}),
|
||||
FiatDisplayCurrency: USD,
|
||||
}
|
||||
|
||||
err = newStorage.RunUpdater(BotOverrides{}, mainConfig, "", false)
|
||||
if err == nil {
|
||||
t.Fatal("Test Failed storage RunUpdater() error cannot be nil")
|
||||
}
|
||||
|
||||
err = newStorage.RunUpdater(BotOverrides{}, mainConfig, "/bla", false)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed storage RunUpdater() error", err)
|
||||
}
|
||||
}
|
||||
127
currency/symbol.go
Normal file
127
currency/symbol.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package currency
|
||||
|
||||
import "errors"
|
||||
|
||||
// symbols map holds the currency name and symbol mappings
|
||||
var symbols = map[*Item]string{
|
||||
ALL.Item: "Lek",
|
||||
AFN.Item: "؋",
|
||||
ARS.Item: "$",
|
||||
AWG.Item: "ƒ",
|
||||
AUD.Item: "$",
|
||||
AZN.Item: "ман",
|
||||
BSD.Item: "$",
|
||||
BBD.Item: "$",
|
||||
BYN.Item: "Br",
|
||||
BZD.Item: "BZ$",
|
||||
BMD.Item: "$",
|
||||
BOB.Item: "$b",
|
||||
BAM.Item: "KM",
|
||||
BWP.Item: "P",
|
||||
BGN.Item: "лв",
|
||||
BRL.Item: "R$",
|
||||
BND.Item: "$",
|
||||
KHR.Item: "៛",
|
||||
CAD.Item: "$",
|
||||
KYD.Item: "$",
|
||||
CLP.Item: "$",
|
||||
CNY.Item: "¥",
|
||||
COP.Item: "$",
|
||||
CRC.Item: "₡",
|
||||
HRK.Item: "kn",
|
||||
CUP.Item: "₱",
|
||||
CZK.Item: "Kč",
|
||||
DKK.Item: "kr",
|
||||
DOP.Item: "RD$",
|
||||
XCD.Item: "$",
|
||||
EGP.Item: "£",
|
||||
SVC.Item: "$",
|
||||
EUR.Item: "€",
|
||||
FKP.Item: "£",
|
||||
FJD.Item: "$",
|
||||
GHS.Item: "¢",
|
||||
GIP.Item: "£",
|
||||
GTQ.Item: "Q",
|
||||
GGP.Item: "£",
|
||||
GYD.Item: "$",
|
||||
HNL.Item: "L",
|
||||
HKD.Item: "$",
|
||||
HUF.Item: "Ft",
|
||||
ISK.Item: "kr",
|
||||
INR.Item: "₹",
|
||||
IDR.Item: "Rp",
|
||||
IRR.Item: "﷼",
|
||||
IMP.Item: "£",
|
||||
ILS.Item: "₪",
|
||||
JMD.Item: "J$",
|
||||
JPY.Item: "¥",
|
||||
JEP.Item: "£",
|
||||
KZT.Item: "лв",
|
||||
KPW.Item: "₩",
|
||||
KRW.Item: "₩",
|
||||
KGS.Item: "лв",
|
||||
LAK.Item: "₭",
|
||||
LBP.Item: "£",
|
||||
LRD.Item: "$",
|
||||
MKD.Item: "ден",
|
||||
MYR.Item: "RM",
|
||||
MUR.Item: "₨",
|
||||
MXN.Item: "$",
|
||||
MNT.Item: "₮",
|
||||
MZN.Item: "MT",
|
||||
NAD.Item: "$",
|
||||
NPR.Item: "₨",
|
||||
ANG.Item: "ƒ",
|
||||
NZD.Item: "$",
|
||||
NIO.Item: "C$",
|
||||
NGN.Item: "₦",
|
||||
NOK.Item: "kr",
|
||||
OMR.Item: "﷼",
|
||||
PKR.Item: "₨",
|
||||
PAB.Item: "B/.",
|
||||
PYG.Item: "Gs",
|
||||
PEN.Item: "S/.",
|
||||
PHP.Item: "₱",
|
||||
PLN.Item: "zł",
|
||||
QAR.Item: "﷼",
|
||||
RON.Item: "lei",
|
||||
RUB.Item: "₽",
|
||||
RUR.Item: "₽",
|
||||
SHP.Item: "£",
|
||||
SAR.Item: "﷼",
|
||||
RSD.Item: "Дин.",
|
||||
SCR.Item: "₨",
|
||||
SGD.Item: "$",
|
||||
SBD.Item: "$",
|
||||
SOS.Item: "S",
|
||||
ZAR.Item: "R",
|
||||
LKR.Item: "₨",
|
||||
SEK.Item: "kr",
|
||||
CHF.Item: "CHF",
|
||||
SRD.Item: "$",
|
||||
SYP.Item: "£",
|
||||
TWD.Item: "NT$",
|
||||
THB.Item: "฿",
|
||||
TTD.Item: "TT$",
|
||||
TRY.Item: "₺",
|
||||
TVD.Item: "$",
|
||||
UAH.Item: "₴",
|
||||
GBP.Item: "£",
|
||||
USD.Item: "$",
|
||||
USDT.Item: "$",
|
||||
UYU.Item: "$U",
|
||||
UZS.Item: "лв",
|
||||
VEF.Item: "Bs",
|
||||
VND.Item: "₫",
|
||||
YER.Item: "﷼",
|
||||
ZWD.Item: "Z$",
|
||||
}
|
||||
|
||||
// GetSymbolByCurrencyName returns a currency symbol
|
||||
func GetSymbolByCurrencyName(currency Code) (string, error) {
|
||||
result, ok := symbols[currency.Item]
|
||||
if !ok {
|
||||
return "", errors.New("currency symbol not found")
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
# GoCryptoTrader package Symbol
|
||||
|
||||
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/page-logo.png?raw=true" width="350px" height="350px" hspace="70">
|
||||
|
||||
|
||||
[](https://travis-ci.org/thrasher-/gocryptotrader)
|
||||
[](https://github.com/thrasher-/gocryptotrader/blob/master/LICENSE)
|
||||
[](https://godoc.org/github.com/thrasher-/gocryptotrader/currency/symbol)
|
||||
[](http://codecov.io/github/thrasher-/gocryptotrader?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/thrasher-/gocryptotrader)
|
||||
|
||||
|
||||
This symbol package is part of the GoCryptoTrader codebase.
|
||||
|
||||
## This is still in active development
|
||||
|
||||
You can track ideas, planned features and what's in progresss on this Trello board: [https://trello.com/b/ZAhMhpOy/gocryptotrader](https://trello.com/b/ZAhMhpOy/gocryptotrader).
|
||||
|
||||
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTQyYjIxNGVhMWU5MDZlOGYzMmE0NTJmM2MzYWY5NGMzMmM4MzUwNTBjZTEzNjIwODM5NDcxODQwZDljMGQyNGY)
|
||||
|
||||
## Current Features for symbol
|
||||
|
||||
+ This package services the currency package by providing symbol mapping.
|
||||
|
||||
+ Example below:
|
||||
```go
|
||||
import "github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
|
||||
// Get the string of the symbol by the currency
|
||||
chineseYen := "CNY"
|
||||
symbol := symbol.GetSymbolByCurrencyName(chineseYen)
|
||||
|
||||
// symbol == "¥"
|
||||
```
|
||||
|
||||
### Please click GoDocs chevron above to view current GoDoc information for this package
|
||||
|
||||
## Contribution
|
||||
|
||||
Please feel free to submit any pull requests or suggest any desired features to be added.
|
||||
|
||||
When submitting a PR, please abide by our coding guidelines:
|
||||
|
||||
+ Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)).
|
||||
+ Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines.
|
||||
+ Code must adhere to our [coding style](https://github.com/thrasher-/gocryptotrader/blob/master/doc/coding_style.md).
|
||||
+ Pull requests need to be based on and opened against the `master` branch.
|
||||
|
||||
## Donations
|
||||
|
||||
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/donate.png?raw=true" hspace="70">
|
||||
|
||||
If this framework helped you in any way, or you would like to support the developers working on it, please donate Bitcoin to:
|
||||
|
||||
***1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB***
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
||||
package symbol
|
||||
package currency
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGetSymbolByCurrencyName(t *testing.T) {
|
||||
expected := "₩"
|
||||
actual, err := GetSymbolByCurrencyName("KPW")
|
||||
actual, err := GetSymbolByCurrencyName(KPW)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed. TestGetSymbolByCurrencyName error: %s", err)
|
||||
}
|
||||
@@ -13,7 +13,7 @@ func TestGetSymbolByCurrencyName(t *testing.T) {
|
||||
t.Errorf("Test failed. TestGetSymbolByCurrencyName differing values")
|
||||
}
|
||||
|
||||
_, err = GetSymbolByCurrencyName("BLAH")
|
||||
_, err = GetSymbolByCurrencyName(Code{})
|
||||
if err == nil {
|
||||
t.Errorf("Test failed. TestGetSymbolByCurrencyNam returned nil on non-existent currency")
|
||||
}
|
||||
22
currency/translation.go
Normal file
22
currency/translation.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package currency
|
||||
|
||||
var translations = map[Code]Code{
|
||||
BTC: XBT,
|
||||
ETH: XETH,
|
||||
DOGE: XDG,
|
||||
USD: USDT,
|
||||
XBT: BTC,
|
||||
XETH: ETH,
|
||||
XDG: DOGE,
|
||||
USDT: USD,
|
||||
}
|
||||
|
||||
// GetTranslation returns similar strings for a particular currency if not found
|
||||
// returns the code back
|
||||
func GetTranslation(currency Code) (Code, bool) {
|
||||
val, ok := translations[currency]
|
||||
if !ok {
|
||||
return currency, ok
|
||||
}
|
||||
return val, ok
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
# GoCryptoTrader package Translation
|
||||
|
||||
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/page-logo.png?raw=true" width="350px" height="350px" hspace="70">
|
||||
|
||||
|
||||
[](https://travis-ci.org/thrasher-/gocryptotrader)
|
||||
[](https://github.com/thrasher-/gocryptotrader/blob/master/LICENSE)
|
||||
[](https://godoc.org/github.com/thrasher-/gocryptotrader/currency/translation)
|
||||
[](http://codecov.io/github/thrasher-/gocryptotrader?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/thrasher-/gocryptotrader)
|
||||
|
||||
|
||||
This translation package is part of the GoCryptoTrader codebase.
|
||||
|
||||
## This is still in active development
|
||||
|
||||
You can track ideas, planned features and what's in progresss on this Trello board: [https://trello.com/b/ZAhMhpOy/gocryptotrader](https://trello.com/b/ZAhMhpOy/gocryptotrader).
|
||||
|
||||
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTQyYjIxNGVhMWU5MDZlOGYzMmE0NTJmM2MzYWY5NGMzMmM4MzUwNTBjZTEzNjIwODM5NDcxODQwZDljMGQyNGY)
|
||||
|
||||
## Current Features for translation
|
||||
|
||||
+ This package services the currency package with translation functions.
|
||||
|
||||
+ Example below:
|
||||
```go
|
||||
import "github.com/thrasher-/gocryptotrader/currency/translation"
|
||||
|
||||
// Is translatable
|
||||
b := translation.HasTranslation("BTC")
|
||||
|
||||
// b == true; translation = XBT
|
||||
```
|
||||
|
||||
### Please click GoDocs chevron above to view current GoDoc information for this package
|
||||
|
||||
## Contribution
|
||||
|
||||
Please feel free to submit any pull requests or suggest any desired features to be added.
|
||||
|
||||
When submitting a PR, please abide by our coding guidelines:
|
||||
|
||||
+ Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)).
|
||||
+ Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines.
|
||||
+ Code must adhere to our [coding style](https://github.com/thrasher-/gocryptotrader/blob/master/doc/coding_style.md).
|
||||
+ Pull requests need to be based on and opened against the `master` branch.
|
||||
|
||||
## Donations
|
||||
|
||||
<img src="https://github.com/thrasher-/gocryptotrader/blob/master/web/src/assets/donate.png?raw=true" hspace="70">
|
||||
|
||||
If this framework helped you in any way, or you would like to support the developers working on it, please donate Bitcoin to:
|
||||
|
||||
***1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB***
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package translation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
)
|
||||
|
||||
var translations = map[pair.CurrencyItem]pair.CurrencyItem{
|
||||
"BTC": "XBT",
|
||||
"ETH": "XETH",
|
||||
"DOGE": "XDG",
|
||||
"USD": "USDT",
|
||||
}
|
||||
|
||||
// GetTranslation returns similar strings for a particular currency
|
||||
func GetTranslation(currency pair.CurrencyItem) (pair.CurrencyItem, error) {
|
||||
for k, v := range translations {
|
||||
if k == currency {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
if v == currency {
|
||||
return k, nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("no translation found for specified currency")
|
||||
}
|
||||
|
||||
// HasTranslation returns whether or not a particular currency has a translation
|
||||
func HasTranslation(currency pair.CurrencyItem) bool {
|
||||
_, err := GetTranslation(currency)
|
||||
return (err == nil)
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package translation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
)
|
||||
|
||||
func TestGetTranslation(t *testing.T) {
|
||||
currencyPair := pair.NewCurrencyPair("BTC", "USD")
|
||||
expected := pair.CurrencyItem("XBT")
|
||||
actual, err := GetTranslation(currencyPair.FirstCurrency)
|
||||
if err != nil {
|
||||
t.Error("GetTranslation: failed to retrieve translation for BTC")
|
||||
}
|
||||
|
||||
if expected != actual {
|
||||
t.Error("GetTranslation: translation result was different to expected result")
|
||||
}
|
||||
|
||||
currencyPair.FirstCurrency = "NEO"
|
||||
_, err = GetTranslation(currencyPair.FirstCurrency)
|
||||
if err == nil {
|
||||
t.Error("GetTranslation: no error on non translatable currency")
|
||||
}
|
||||
|
||||
expected = "BTC"
|
||||
currencyPair.FirstCurrency = "XBT"
|
||||
|
||||
actual, err = GetTranslation(currencyPair.FirstCurrency)
|
||||
if err != nil {
|
||||
t.Error("GetTranslation: failed to retrieve translation for BTC")
|
||||
}
|
||||
|
||||
if expected != actual {
|
||||
t.Error("GetTranslation: translation result was different to expected result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasTranslation(t *testing.T) {
|
||||
currencyPair := pair.NewCurrencyPair("BTC", "USD")
|
||||
expected := true
|
||||
actual := HasTranslation(currencyPair.FirstCurrency)
|
||||
if expected != actual {
|
||||
t.Error("HasTranslation: translation result was different to expected result")
|
||||
}
|
||||
|
||||
currencyPair.FirstCurrency = "XBT"
|
||||
expected = true
|
||||
actual = HasTranslation(currencyPair.FirstCurrency)
|
||||
if expected != actual {
|
||||
t.Error("HasTranslation: translation result was different to expected result")
|
||||
}
|
||||
|
||||
currencyPair.FirstCurrency = "NEO"
|
||||
expected = false
|
||||
actual = HasTranslation(currencyPair.FirstCurrency)
|
||||
if expected != actual {
|
||||
t.Error("HasTranslation: translation result was different to expected result")
|
||||
}
|
||||
}
|
||||
34
currency/translation_test.go
Normal file
34
currency/translation_test.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package currency
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGetTranslation(t *testing.T) {
|
||||
currencyPair := NewPair(BTC, USD)
|
||||
expected := XBT
|
||||
actual, ok := GetTranslation(currencyPair.Base)
|
||||
if !ok {
|
||||
t.Error("GetTranslation: failed to retrieve translation for BTC")
|
||||
}
|
||||
|
||||
if expected != actual {
|
||||
t.Error("GetTranslation: translation result was different to expected result")
|
||||
}
|
||||
|
||||
currencyPair.Base = NEO
|
||||
_, ok = GetTranslation(currencyPair.Base)
|
||||
if ok {
|
||||
t.Error("GetTranslation: no error on non translatable currency")
|
||||
}
|
||||
|
||||
expected = BTC
|
||||
currencyPair.Base = XBT
|
||||
|
||||
actual, ok = GetTranslation(currencyPair.Base)
|
||||
if !ok {
|
||||
t.Error("GetTranslation: failed to retrieve translation for BTC")
|
||||
}
|
||||
|
||||
if expected != actual {
|
||||
t.Error("GetTranslation: translation result was different to expected result")
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ package events
|
||||
// func TestAddEvent(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := pair.NewCurrencyPair("BTC", "USD")
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// eventID, err := AddEvent("ANX", "price", ">,==", pair, "SPOT", actionTest)
|
||||
// if err != nil && eventID != 0 {
|
||||
// t.Errorf("Test Failed. AddEvent: Error, %s", err)
|
||||
@@ -59,7 +59,7 @@ package events
|
||||
// func TestRemoveEvent(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := pair.NewCurrencyPair("BTC", "USD")
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// eventID, err := AddEvent("ANX", "price", ">,==", pair, "SPOT", actionTest)
|
||||
// if err != nil && eventID != 0 {
|
||||
// t.Errorf("Test Failed. RemoveEvent: Error, %s", err)
|
||||
@@ -75,7 +75,7 @@ package events
|
||||
// func TestGetEventCounter(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := pair.NewCurrencyPair("BTC", "USD")
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// one, err := AddEvent("ANX", "price", ">,==", pair, "SPOT", actionTest)
|
||||
// if err != nil {
|
||||
// t.Errorf("Test Failed. GetEventCounter: Error, %s", err)
|
||||
@@ -114,7 +114,7 @@ package events
|
||||
// func TestExecuteAction(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := pair.NewCurrencyPair("BTC", "USD")
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// one, err := AddEvent("ANX", "price", ">,==", pair, "SPOT", actionTest)
|
||||
// if err != nil {
|
||||
// t.Fatalf("Test Failed. ExecuteAction: Error, %s", err)
|
||||
@@ -160,7 +160,7 @@ package events
|
||||
// func TestEventToString(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := pair.NewCurrencyPair("BTC", "USD")
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// one, err := AddEvent("ANX", "price", ">,==", pair, "SPOT", actionTest)
|
||||
// if err != nil {
|
||||
// t.Errorf("Test Failed. EventToString: Error, %s", err)
|
||||
@@ -180,7 +180,7 @@ package events
|
||||
// testSetup(t)
|
||||
//
|
||||
// // Test invalid currency pair
|
||||
// newPair := pair.NewCurrencyPair("A", "B")
|
||||
// newPair := currency.NewPairFromStrings("A", "B")
|
||||
// one, err := AddEvent("ANX", "price", ">=,10", newPair, "SPOT", actionTest)
|
||||
// if err != nil {
|
||||
// t.Errorf("Test Failed. CheckCondition: Error, %s", err)
|
||||
@@ -193,7 +193,7 @@ package events
|
||||
// // Test last price == 0
|
||||
// var tickerNew ticker.Price
|
||||
// tickerNew.Last = 0
|
||||
// newPair = pair.NewCurrencyPair("BTC", "USD")
|
||||
// newPair = currency.NewPairFromStrings("BTC", "USD")
|
||||
// ticker.ProcessTicker("ANX", newPair, tickerNew, ticker.Spot)
|
||||
// Events[one].Pair = newPair
|
||||
// conditionBool = Events[one].CheckCondition()
|
||||
@@ -287,7 +287,7 @@ package events
|
||||
// func TestCheckEvents(t *testing.T) {
|
||||
// testSetup(t)
|
||||
//
|
||||
// pair := pair.NewCurrencyPair("BTC", "USD")
|
||||
// pair := currency.NewPairFromStrings("BTC", "USD")
|
||||
// _, err := AddEvent("ANX", "price", ">=,10", pair, "SPOT", actionTest)
|
||||
// if err != nil {
|
||||
// t.Fatal("Test failed. TestChcheckEvents add event")
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/thrasher-/gocryptotrader/communications"
|
||||
"github.com/thrasher-/gocryptotrader/communications/base"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
@@ -42,7 +42,7 @@ type Event struct {
|
||||
Exchange string
|
||||
Item string
|
||||
Condition string
|
||||
Pair pair.CurrencyPair
|
||||
Pair currency.Pair
|
||||
Asset string
|
||||
Action string
|
||||
Executed bool
|
||||
@@ -60,7 +60,7 @@ 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) {
|
||||
func AddEvent(exchange, item, condition string, currencyPair currency.Pair, asset, action string) (int, error) {
|
||||
err := IsValidEvent(exchange, item, condition, action)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -129,8 +129,13 @@ func (e *Event) ExecuteAction() bool {
|
||||
func (e *Event) String() string {
|
||||
condition := common.SplitStrings(e.Condition, ",")
|
||||
return fmt.Sprintf(
|
||||
"If the %s%s [%s] %s on %s is %s then %s.", e.Pair.FirstCurrency.String(),
|
||||
e.Pair.SecondCurrency.String(), e.Asset, e.Item, e.Exchange, condition[0]+" "+condition[1], e.Action,
|
||||
"If the %s%s [%s] %s on %s is %s then %s.", e.Pair.Base.String(),
|
||||
e.Pair.Quote.String(),
|
||||
e.Asset,
|
||||
e.Item,
|
||||
e.Exchange,
|
||||
condition[0]+" "+condition[1],
|
||||
e.Action,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -541,10 +540,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
if areTestAPIKeysSet(a) && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "_",
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.USD,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "_",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.USD,
|
||||
}
|
||||
response, err := a.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if !areTestAPIKeysSet(a) && err == nil {
|
||||
@@ -567,7 +566,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC)
|
||||
currencyPair := currency.NewPair(currency.BTC, currency.LTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -593,7 +592,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC)
|
||||
currencyPair := currency.NewPair(currency.BTC, currency.LTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -631,7 +630,7 @@ func TestWithdraw(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.BTC,
|
||||
Currency: currency.BTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
AddressTag: "0123456789",
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -26,7 +26,7 @@ func (a *Alphapoint) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
var currencies []exchange.AccountCurrencyInfo
|
||||
for i := 0; i < len(account.Currencies); i++ {
|
||||
var exchangeCurrency exchange.AccountCurrencyInfo
|
||||
exchangeCurrency.CurrencyName = account.Currencies[i].Name
|
||||
exchangeCurrency.CurrencyName = currency.NewCode(account.Currencies[i].Name)
|
||||
exchangeCurrency.TotalValue = float64(account.Currencies[i].Balance)
|
||||
exchangeCurrency.Hold = float64(account.Currencies[i].Hold)
|
||||
|
||||
@@ -41,9 +41,9 @@ func (a *Alphapoint) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (a *Alphapoint) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (a *Alphapoint) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
tick, err := a.GetTicker(p.Pair().String())
|
||||
tick, err := a.GetTicker(p.String())
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
@@ -55,12 +55,17 @@ func (a *Alphapoint) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker
|
||||
tickerPrice.High = tick.High
|
||||
tickerPrice.Volume = tick.Volume
|
||||
tickerPrice.Last = tick.Last
|
||||
ticker.ProcessTicker(a.GetName(), p, tickerPrice, assetType)
|
||||
|
||||
err = ticker.ProcessTicker(a.GetName(), tickerPrice, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
|
||||
return ticker.GetTicker(a.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (a *Alphapoint) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (a *Alphapoint) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tick, err := ticker.GetTicker(a.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return a.UpdateTicker(p, assetType)
|
||||
@@ -69,30 +74,40 @@ func (a *Alphapoint) GetTickerPrice(p pair.CurrencyPair, assetType string) (tick
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (a *Alphapoint) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (a *Alphapoint) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
orderbookNew, err := a.GetOrderbook(p.Pair().String())
|
||||
orderbookNew, err := a.GetOrderbook(p.String())
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
for x := range orderbookNew.Bids {
|
||||
data := orderbookNew.Bids[x]
|
||||
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Amount: data.Quantity, Price: data.Price})
|
||||
orderBook.Bids = append(orderBook.Bids,
|
||||
orderbook.Item{Amount: data.Quantity, Price: data.Price})
|
||||
}
|
||||
|
||||
for x := range orderbookNew.Asks {
|
||||
data := orderbookNew.Asks[x]
|
||||
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data.Quantity, Price: data.Price})
|
||||
orderBook.Asks = append(orderBook.Asks,
|
||||
orderbook.Item{Amount: data.Quantity, Price: data.Price})
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(a.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(a.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = a.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(a.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns the orderbook for a currency pair
|
||||
func (a *Alphapoint) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(a.GetName(), p, assetType)
|
||||
func (a *Alphapoint) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(a.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return a.UpdateOrderbook(p, assetType)
|
||||
}
|
||||
@@ -108,7 +123,7 @@ func (a *Alphapoint) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (a *Alphapoint) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (a *Alphapoint) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
@@ -116,10 +131,14 @@ func (a *Alphapoint) GetExchangeHistory(p pair.CurrencyPair, assetType string) (
|
||||
|
||||
// SubmitOrder submits a new order and returns a true value when
|
||||
// successfully submitted
|
||||
func (a *Alphapoint) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
func (a *Alphapoint) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
|
||||
response, err := a.CreateOrder(p.Pair().String(), side.ToString(), orderType.ToString(), amount, price)
|
||||
response, err := a.CreateOrder(p.String(),
|
||||
side.ToString(),
|
||||
orderType.ToString(),
|
||||
amount, price)
|
||||
|
||||
if response > 0 {
|
||||
submitOrderResponse.OrderID = fmt.Sprintf("%v", response)
|
||||
}
|
||||
@@ -172,7 +191,7 @@ func (a *Alphapoint) GetOrderInfo(orderID string) (float64, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (a *Alphapoint) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) (string, error) {
|
||||
func (a *Alphapoint) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) {
|
||||
addreses, err := a.GetDepositAddresses()
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -87,9 +87,9 @@ func (a *ANX) Setup(exch config.ExchangeConfig) {
|
||||
a.SetHTTPClientUserAgent(exch.HTTPUserAgent)
|
||||
a.RESTPollingDelay = exch.RESTPollingDelay
|
||||
a.Verbose = exch.Verbose
|
||||
a.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
a.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
a.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
a.BaseCurrencies = exch.BaseCurrencies
|
||||
a.AvailablePairs = exch.AvailablePairs
|
||||
a.EnabledPairs = exch.EnabledPairs
|
||||
err := a.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -451,9 +451,9 @@ func (a *ANX) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
case exchange.CryptocurrencyTradeFee:
|
||||
fee = a.calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount, feeBuilder.IsMaker)
|
||||
case exchange.CryptocurrencyWithdrawalFee:
|
||||
fee = getCryptocurrencyWithdrawalFee(feeBuilder.FirstCurrency)
|
||||
fee = getCryptocurrencyWithdrawalFee(feeBuilder.Pair.Base)
|
||||
case exchange.InternationalBankWithdrawalFee:
|
||||
fee = getInternationalBankWithdrawalFee(feeBuilder.CurrencyItem, feeBuilder.Amount)
|
||||
fee = getInternationalBankWithdrawalFee(feeBuilder.FiatCurrency, feeBuilder.Amount)
|
||||
}
|
||||
if fee < 0 {
|
||||
fee = 0
|
||||
@@ -473,15 +473,15 @@ func (a *ANX) calculateTradingFee(purchasePrice, amount float64, isMaker bool) f
|
||||
return fee
|
||||
}
|
||||
|
||||
func getCryptocurrencyWithdrawalFee(currency string) float64 {
|
||||
return WithdrawalFees[currency]
|
||||
func getCryptocurrencyWithdrawalFee(c currency.Code) float64 {
|
||||
return WithdrawalFees[c]
|
||||
}
|
||||
|
||||
func getInternationalBankWithdrawalFee(currency string, amount float64) float64 {
|
||||
func getInternationalBankWithdrawalFee(c currency.Code, amount float64) float64 {
|
||||
var fee float64
|
||||
|
||||
if currency == symbol.HKD {
|
||||
fee = 250 + (WithdrawalFees[currency] * amount)
|
||||
if c == currency.HKD {
|
||||
fee = 250 + (WithdrawalFees[c] * amount)
|
||||
}
|
||||
// TODO, other fiat currencies require consultation with ANXPRO
|
||||
return fee
|
||||
|
||||
@@ -5,8 +5,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -131,13 +130,11 @@ func TestGetAPIKey(t *testing.T) {
|
||||
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +194,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := a.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -206,7 +203,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := a.GetFee(feeBuilder); resp != float64(250.01) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(250.01), resp)
|
||||
t.Error(err)
|
||||
@@ -275,10 +272,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "_",
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.USD,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "_",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.USD,
|
||||
}
|
||||
response, err := a.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -296,7 +293,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC)
|
||||
currencyPair := currency.NewPair(currency.BTC, currency.LTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -321,7 +318,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.BTC, symbol.LTC)
|
||||
currencyPair := currency.NewPair(currency.BTC, currency.LTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -374,7 +371,7 @@ func TestWithdraw(t *testing.T) {
|
||||
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.BTC,
|
||||
Currency: currency.BTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
AddressTag: "0123456789",
|
||||
@@ -422,12 +419,12 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if areTestAPIKeysSet() {
|
||||
_, err := a.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := a.GetDepositAddress(currency.BTC, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := a.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := a.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package anx
|
||||
|
||||
import "github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
import "github.com/thrasher-/gocryptotrader/currency"
|
||||
|
||||
// List of strings
|
||||
const (
|
||||
@@ -9,8 +9,8 @@ const (
|
||||
CancelOrderWrongState string = "ORDER_CANCEL_WRONG_STATE"
|
||||
)
|
||||
|
||||
// Currency holds the currency information
|
||||
type Currency struct {
|
||||
// CurrencyData holds the currency information
|
||||
type CurrencyData struct {
|
||||
Decimals int `json:"decimals"`
|
||||
MinOrderSize float64 `json:"minOrderSize"`
|
||||
MaxOrderSize float64 `json:"maxOrderSize"`
|
||||
@@ -41,10 +41,10 @@ type Currency struct {
|
||||
}
|
||||
|
||||
// Currencies stores a list of currencies
|
||||
type Currencies map[string]Currency
|
||||
type Currencies map[string]CurrencyData
|
||||
|
||||
// CurrencyPair holds the currency information
|
||||
type CurrencyPair struct {
|
||||
// CurrencyPairData holds the currency information
|
||||
type CurrencyPairData struct {
|
||||
PriceDecimals int `json:"priceDecimals"`
|
||||
EngineSettings struct {
|
||||
TradingEnabled bool `json:"tradingEnabled"`
|
||||
@@ -88,7 +88,7 @@ type Amount struct {
|
||||
}
|
||||
|
||||
// CurrencyPairs stores currency pair info
|
||||
type CurrencyPairs map[string]CurrencyPair
|
||||
type CurrencyPairs map[string]CurrencyPairData
|
||||
|
||||
// CurrenciesStore stores the available cryptocurrencies
|
||||
// and fiat currencies
|
||||
@@ -195,13 +195,13 @@ type Depth struct {
|
||||
|
||||
// WithdrawalFees the large list of predefined withdrawal fees
|
||||
// Prone to change
|
||||
var WithdrawalFees = map[string]float64{
|
||||
symbol.BTC: 0.002,
|
||||
symbol.DOGE: 0.1,
|
||||
symbol.ETH: 0.005,
|
||||
symbol.GNT: 0.001,
|
||||
symbol.LTC: 0.02,
|
||||
symbol.OAX: 0.001,
|
||||
symbol.XRP: 1,
|
||||
symbol.HKD: 0.01,
|
||||
var WithdrawalFees = map[currency.Code]float64{
|
||||
currency.BTC: 0.002,
|
||||
currency.DOGE: 0.1,
|
||||
currency.ETH: 0.005,
|
||||
currency.GNT: 0.001,
|
||||
currency.LTC: 0.02,
|
||||
currency.OAX: 0.001,
|
||||
currency.XRP: 1,
|
||||
currency.HKD: 0.01,
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -31,17 +31,25 @@ func (a *ANX) Run() {
|
||||
log.Debugf("%s %d currencies enabled: %s.\n", a.GetName(), len(a.EnabledPairs), a.EnabledPairs)
|
||||
}
|
||||
|
||||
exchangeProducts, err := a.GetTradablePairs()
|
||||
tradablePairs, err := a.GetTradablePairs()
|
||||
if err != nil {
|
||||
log.Debugf("%s Failed to get available symbols.\n", a.GetName())
|
||||
} else {
|
||||
forceUpgrade := false
|
||||
if !common.StringDataContains(a.EnabledPairs, "_") || !common.StringDataContains(a.AvailablePairs, "_") {
|
||||
if !common.StringDataContains(a.EnabledPairs.Strings(), "_") ||
|
||||
!common.StringDataContains(a.AvailablePairs.Strings(), "_") {
|
||||
forceUpgrade = true
|
||||
}
|
||||
|
||||
if forceUpgrade {
|
||||
enabledPairs := []string{"BTC_USD,BTC_HKD,BTC_EUR,BTC_CAD,BTC_AUD,BTC_SGD,BTC_JPY,BTC_GBP,BTC_NZD,LTC_BTC,DOG_EBTC,STR_BTC,XRP_BTC"}
|
||||
newPairs := []string{"BTC_USD,BTC_HKD,BTC_EUR,BTC_CAD,BTC_AUD,BTC_SGD,BTC_JPY,BTC_GBP,BTC_NZD,LTC_BTC,DOG_EBTC,STR_BTC,XRP_BTC"}
|
||||
|
||||
var enabledPairs currency.Pairs
|
||||
for _, p := range newPairs {
|
||||
enabledPairs = append(enabledPairs,
|
||||
currency.NewPairDelimiter(p, "_"))
|
||||
}
|
||||
|
||||
log.Warn("Enabled pairs for ANX reset due to config upgrade, please enable the ones you would like again.")
|
||||
|
||||
err = a.UpdateCurrencies(enabledPairs, true, true)
|
||||
@@ -49,6 +57,13 @@ func (a *ANX) Run() {
|
||||
log.Errorf("%s Failed to get config.\n", a.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
var exchangeProducts currency.Pairs
|
||||
for _, p := range tradablePairs {
|
||||
exchangeProducts = append(exchangeProducts,
|
||||
currency.NewPairDelimiter(p, "_"))
|
||||
}
|
||||
|
||||
err = a.UpdateCurrencies(exchangeProducts, false, forceUpgrade)
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to get config.\n", a.GetName())
|
||||
@@ -72,7 +87,7 @@ func (a *ANX) GetTradablePairs() ([]string, error) {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (a *ANX) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (a *ANX) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
tick, err := a.GetTicker(exchange.FormatExchangeCurrency(a.GetName(), p).String())
|
||||
if err != nil {
|
||||
@@ -134,12 +149,17 @@ func (a *ANX) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price,
|
||||
} else {
|
||||
tickerPrice.High = 0
|
||||
}
|
||||
ticker.ProcessTicker(a.GetName(), p, tickerPrice, assetType)
|
||||
|
||||
err = ticker.ProcessTicker(a.GetName(), tickerPrice, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
|
||||
return ticker.GetTicker(a.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (a *ANX) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (a *ANX) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tickerNew, err := ticker.GetTicker(a.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return a.UpdateTicker(p, assetType)
|
||||
@@ -148,8 +168,8 @@ func (a *ANX) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Pric
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns the orderbook for a currency pair
|
||||
func (a *ANX) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(a.GetName(), p, assetType)
|
||||
func (a *ANX) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(a.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return a.UpdateOrderbook(p, assetType)
|
||||
}
|
||||
@@ -157,7 +177,7 @@ func (a *ANX) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.B
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (a *ANX) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (a *ANX) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
orderbookNew, err := a.GetDepth(exchange.FormatExchangeCurrency(a.GetName(), p).String())
|
||||
if err != nil {
|
||||
@@ -178,8 +198,15 @@ func (a *ANX) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.
|
||||
Amount: orderbookNew.Data.Bids[x].Amount})
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(a.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(a.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = a.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(a.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetAccountInfo retrieves balances for all enabled currencies on the
|
||||
@@ -193,9 +220,9 @@ func (a *ANX) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
}
|
||||
|
||||
var balance []exchange.AccountCurrencyInfo
|
||||
for currency, info := range raw.Wallets {
|
||||
for c, info := range raw.Wallets {
|
||||
balance = append(balance, exchange.AccountCurrencyInfo{
|
||||
CurrencyName: currency,
|
||||
CurrencyName: currency.NewCode(c),
|
||||
TotalValue: info.AvailableBalance.Value,
|
||||
Hold: info.Balance.Value,
|
||||
})
|
||||
@@ -217,14 +244,14 @@ func (a *ANX) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (a *ANX) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (a *ANX) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (a *ANX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
func (a *ANX) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
|
||||
var isBuying bool
|
||||
@@ -240,9 +267,9 @@ func (a *ANX) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderTyp
|
||||
|
||||
response, err := a.NewOrder(orderType.ToString(),
|
||||
isBuying,
|
||||
p.FirstCurrency.String(),
|
||||
p.Base.String(),
|
||||
amount,
|
||||
p.SecondCurrency.String(),
|
||||
p.Quote.String(),
|
||||
amount,
|
||||
limitPriceInSettlementCurrency,
|
||||
false,
|
||||
@@ -309,7 +336,7 @@ func (a *ANX) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (a *ANX) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) (string, error) {
|
||||
func (a *ANX) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) {
|
||||
return a.GetDepositAddressByCurrency(cryptocurrency.String(), "", false)
|
||||
}
|
||||
|
||||
@@ -356,21 +383,23 @@ func (a *ANX) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exc
|
||||
orderType := exchange.OrderType(strings.ToUpper(order.OrderType))
|
||||
|
||||
orderDetail := exchange.OrderDetail{
|
||||
Amount: order.TradedCurrencyAmount,
|
||||
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.TradedCurrency, order.SettlementCurrency, a.ConfigCurrencyPairFormat.Delimiter),
|
||||
OrderDate: orderDate,
|
||||
Exchange: a.Name,
|
||||
ID: order.OrderID,
|
||||
OrderType: orderType,
|
||||
Price: order.SettlementCurrencyAmount,
|
||||
Status: order.OrderStatus,
|
||||
Amount: order.TradedCurrencyAmount,
|
||||
CurrencyPair: currency.NewPairWithDelimiter(order.TradedCurrency,
|
||||
order.SettlementCurrency, a.ConfigCurrencyPairFormat.Delimiter),
|
||||
OrderDate: orderDate,
|
||||
Exchange: a.Name,
|
||||
ID: order.OrderID,
|
||||
OrderType: orderType,
|
||||
Price: order.SettlementCurrencyAmount,
|
||||
Status: order.OrderStatus,
|
||||
}
|
||||
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
|
||||
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
|
||||
|
||||
return orders, nil
|
||||
@@ -390,21 +419,24 @@ func (a *ANX) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exc
|
||||
orderType := exchange.OrderType(strings.ToUpper(order.OrderType))
|
||||
|
||||
orderDetail := exchange.OrderDetail{
|
||||
Amount: order.TradedCurrencyAmount,
|
||||
OrderDate: orderDate,
|
||||
Exchange: a.Name,
|
||||
ID: order.OrderID,
|
||||
OrderType: orderType,
|
||||
Price: order.SettlementCurrencyAmount,
|
||||
Status: order.OrderStatus,
|
||||
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.TradedCurrency, order.SettlementCurrency, a.ConfigCurrencyPairFormat.Delimiter),
|
||||
Amount: order.TradedCurrencyAmount,
|
||||
OrderDate: orderDate,
|
||||
Exchange: a.Name,
|
||||
ID: order.OrderID,
|
||||
OrderType: orderType,
|
||||
Price: order.SettlementCurrencyAmount,
|
||||
Status: order.OrderStatus,
|
||||
CurrencyPair: currency.NewPairWithDelimiter(order.TradedCurrency,
|
||||
order.SettlementCurrency,
|
||||
a.ConfigCurrencyPairFormat.Delimiter),
|
||||
}
|
||||
|
||||
orders = append(orders, orderDetail)
|
||||
}
|
||||
|
||||
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
|
||||
|
||||
return orders, nil
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -111,9 +112,9 @@ func (b *Binance) Setup(exch config.ExchangeConfig) {
|
||||
b.SetHTTPClientUserAgent(exch.HTTPUserAgent)
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
err := b.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -706,7 +707,7 @@ func (b *Binance) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
}
|
||||
fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount, multiplier)
|
||||
case exchange.CryptocurrencyWithdrawalFee:
|
||||
fee = getCryptocurrencyWithdrawalFee(feeBuilder.FirstCurrency)
|
||||
fee = getCryptocurrencyWithdrawalFee(feeBuilder.Pair.Base)
|
||||
}
|
||||
if fee < 0 {
|
||||
fee = 0
|
||||
@@ -735,8 +736,8 @@ func calculateTradingFee(purchasePrice, amount, multiplier float64) float64 {
|
||||
}
|
||||
|
||||
// getCryptocurrencyWithdrawalFee returns the fee for withdrawing from the exchange
|
||||
func getCryptocurrencyWithdrawalFee(currency string) float64 {
|
||||
return WithdrawalFees[currency]
|
||||
func getCryptocurrencyWithdrawalFee(c currency.Code) float64 {
|
||||
return WithdrawalFees[c]
|
||||
}
|
||||
|
||||
// WithdrawCrypto sends cryptocurrency to the address of your choosing
|
||||
|
||||
@@ -5,8 +5,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -234,13 +233,10 @@ func TestGetAccount(t *testing.T) {
|
||||
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +299,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -312,7 +308,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -342,7 +338,9 @@ func TestGetActiveOrders(t *testing.T) {
|
||||
t.Error("Expected: 'At least one currency is required to fetch order history'. received nil")
|
||||
}
|
||||
|
||||
getOrdersRequest.Currencies = []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)}
|
||||
getOrdersRequest.Currencies = []currency.Pair{
|
||||
currency.NewPair(currency.LTC, currency.BTC),
|
||||
}
|
||||
|
||||
_, err = b.GetActiveOrders(getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
@@ -365,7 +363,9 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
t.Error("Expected: 'At least one currency is required to fetch order history'. received nil")
|
||||
}
|
||||
|
||||
getOrdersRequest.Currencies = []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)}
|
||||
getOrdersRequest.Currencies = []currency.Pair{
|
||||
currency.NewPair(currency.LTC,
|
||||
currency.BTC)}
|
||||
|
||||
_, err = b.GetOrderHistory(getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
@@ -390,10 +390,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "",
|
||||
FirstCurrency: symbol.LTC,
|
||||
SecondCurrency: symbol.BTC,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "",
|
||||
Base: currency.LTC,
|
||||
Quote: currency.BTC,
|
||||
}
|
||||
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -407,7 +407,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -429,7 +429,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -482,7 +482,7 @@ func TestWithdraw(t *testing.T) {
|
||||
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.BTC,
|
||||
Currency: currency.BTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
@@ -530,12 +530,12 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if areTestAPIKeysSet() {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package binance
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
)
|
||||
|
||||
// Response holds basic binance api response data
|
||||
@@ -450,171 +450,171 @@ var (
|
||||
|
||||
// WithdrawalFees the large list of predefined withdrawal fees
|
||||
// Prone to change
|
||||
var WithdrawalFees = map[string]float64{
|
||||
symbol.BNB: 0.13,
|
||||
symbol.BTC: 0.0005,
|
||||
symbol.NEO: 0,
|
||||
symbol.ETH: 0.01,
|
||||
symbol.LTC: 0.001,
|
||||
symbol.QTUM: 0.01,
|
||||
symbol.EOS: 0.1,
|
||||
symbol.SNT: 35,
|
||||
symbol.BNT: 1,
|
||||
symbol.GAS: 0,
|
||||
symbol.BCC: 0.001,
|
||||
symbol.BTM: 5,
|
||||
symbol.USDT: 3.4,
|
||||
symbol.HCC: 0.0005,
|
||||
symbol.OAX: 6.5,
|
||||
symbol.DNT: 54,
|
||||
symbol.MCO: 0.31,
|
||||
symbol.ICN: 3.5,
|
||||
symbol.ZRX: 1.9,
|
||||
symbol.OMG: 0.4,
|
||||
symbol.WTC: 0.5,
|
||||
symbol.LRC: 12.3,
|
||||
symbol.LLT: 67.8,
|
||||
symbol.YOYO: 1,
|
||||
symbol.TRX: 1,
|
||||
symbol.STRAT: 0.1,
|
||||
symbol.SNGLS: 54,
|
||||
symbol.BQX: 3.9,
|
||||
symbol.KNC: 3.5,
|
||||
symbol.SNM: 25,
|
||||
symbol.FUN: 86,
|
||||
symbol.LINK: 4,
|
||||
symbol.XVG: 0.1,
|
||||
symbol.CTR: 35,
|
||||
symbol.SALT: 2.3,
|
||||
symbol.MDA: 2.3,
|
||||
symbol.IOTA: 0.5,
|
||||
symbol.SUB: 11.4,
|
||||
symbol.ETC: 0.01,
|
||||
symbol.MTL: 2,
|
||||
symbol.MTH: 45,
|
||||
symbol.ENG: 2.2,
|
||||
symbol.AST: 14.4,
|
||||
symbol.DASH: 0.002,
|
||||
symbol.BTG: 0.001,
|
||||
symbol.EVX: 2.8,
|
||||
symbol.REQ: 29.9,
|
||||
symbol.VIB: 30,
|
||||
symbol.POWR: 8.2,
|
||||
symbol.ARK: 0.2,
|
||||
symbol.XRP: 0.25,
|
||||
symbol.MOD: 2,
|
||||
symbol.ENJ: 26,
|
||||
symbol.STORJ: 5.1,
|
||||
symbol.KMD: 0.002,
|
||||
symbol.RCN: 47,
|
||||
symbol.NULS: 0.01,
|
||||
symbol.RDN: 2.5,
|
||||
symbol.XMR: 0.04,
|
||||
symbol.DLT: 19.8,
|
||||
symbol.AMB: 8.9,
|
||||
symbol.BAT: 8,
|
||||
symbol.ZEC: 0.005,
|
||||
symbol.BCPT: 14.5,
|
||||
symbol.ARN: 3,
|
||||
symbol.GVT: 0.13,
|
||||
symbol.CDT: 81,
|
||||
symbol.GXS: 0.3,
|
||||
symbol.POE: 134,
|
||||
symbol.QSP: 36,
|
||||
symbol.BTS: 1,
|
||||
symbol.XZC: 0.02,
|
||||
symbol.LSK: 0.1,
|
||||
symbol.TNT: 47,
|
||||
symbol.FUEL: 79,
|
||||
symbol.MANA: 18,
|
||||
symbol.BCD: 0.01,
|
||||
symbol.DGD: 0.04,
|
||||
symbol.ADX: 6.3,
|
||||
symbol.ADA: 1,
|
||||
symbol.PPT: 0.41,
|
||||
symbol.CMT: 12,
|
||||
symbol.XLM: 0.01,
|
||||
symbol.CND: 58,
|
||||
symbol.LEND: 84,
|
||||
symbol.WABI: 6.6,
|
||||
symbol.SBTC: 0.0005,
|
||||
symbol.BCX: 0.5,
|
||||
symbol.WAVES: 0.002,
|
||||
symbol.TNB: 139,
|
||||
symbol.GTO: 20,
|
||||
symbol.ICX: 0.02,
|
||||
symbol.OST: 32,
|
||||
symbol.ELF: 3.9,
|
||||
symbol.AION: 3.2,
|
||||
symbol.CVC: 10.9,
|
||||
symbol.REP: 0.2,
|
||||
symbol.GNT: 8.9,
|
||||
symbol.DATA: 37,
|
||||
symbol.ETF: 1,
|
||||
symbol.BRD: 3.8,
|
||||
symbol.NEBL: 0.01,
|
||||
symbol.VIBE: 17.3,
|
||||
symbol.LUN: 0.36,
|
||||
symbol.CHAT: 60.7,
|
||||
symbol.RLC: 3.4,
|
||||
symbol.INS: 3.5,
|
||||
symbol.IOST: 105.6,
|
||||
symbol.STEEM: 0.01,
|
||||
symbol.NANO: 0.01,
|
||||
symbol.AE: 1.3,
|
||||
symbol.VIA: 0.01,
|
||||
symbol.BLZ: 10.3,
|
||||
symbol.SYS: 1,
|
||||
symbol.NCASH: 247.6,
|
||||
symbol.POA: 0.01,
|
||||
symbol.ONT: 1,
|
||||
symbol.ZIL: 37.2,
|
||||
symbol.STORM: 152,
|
||||
symbol.XEM: 4,
|
||||
symbol.WAN: 0.1,
|
||||
symbol.WPR: 43.4,
|
||||
symbol.QLC: 1,
|
||||
symbol.GRS: 0.2,
|
||||
symbol.CLOAK: 0.02,
|
||||
symbol.LOOM: 11.9,
|
||||
symbol.BCN: 1,
|
||||
symbol.TUSD: 1.35,
|
||||
symbol.ZEN: 0.002,
|
||||
symbol.SKY: 0.01,
|
||||
symbol.THETA: 24,
|
||||
symbol.IOTX: 90.5,
|
||||
symbol.QKC: 24.6,
|
||||
symbol.AGI: 29.81,
|
||||
symbol.NXS: 0.02,
|
||||
symbol.SC: 0.1,
|
||||
symbol.EON: 10,
|
||||
symbol.NPXS: 897,
|
||||
symbol.KEY: 223,
|
||||
symbol.NAS: 0.1,
|
||||
symbol.ADD: 100,
|
||||
symbol.MEETONE: 300,
|
||||
symbol.ATD: 100,
|
||||
symbol.MFT: 175,
|
||||
symbol.EOP: 5,
|
||||
symbol.DENT: 596,
|
||||
symbol.IQ: 50,
|
||||
symbol.ARDR: 2,
|
||||
symbol.HOT: 1210,
|
||||
symbol.VET: 100,
|
||||
symbol.DOCK: 68,
|
||||
symbol.POLY: 7,
|
||||
symbol.VTHO: 21,
|
||||
symbol.ONG: 0.1,
|
||||
symbol.PHX: 1,
|
||||
symbol.HC: 0.005,
|
||||
symbol.GO: 0.01,
|
||||
symbol.PAX: 1.4,
|
||||
symbol.EDO: 1.3,
|
||||
symbol.WINGS: 8.9,
|
||||
symbol.NAV: 0.2,
|
||||
symbol.TRIG: 49.1,
|
||||
symbol.APPC: 12.4,
|
||||
symbol.PIVX: 0.02,
|
||||
var WithdrawalFees = map[currency.Code]float64{
|
||||
currency.BNB: 0.13,
|
||||
currency.BTC: 0.0005,
|
||||
currency.NEO: 0,
|
||||
currency.ETH: 0.01,
|
||||
currency.LTC: 0.001,
|
||||
currency.QTUM: 0.01,
|
||||
currency.EOS: 0.1,
|
||||
currency.SNT: 35,
|
||||
currency.BNT: 1,
|
||||
currency.GAS: 0,
|
||||
currency.BCC: 0.001,
|
||||
currency.BTM: 5,
|
||||
currency.USDT: 3.4,
|
||||
currency.HCC: 0.0005,
|
||||
currency.OAX: 6.5,
|
||||
currency.DNT: 54,
|
||||
currency.MCO: 0.31,
|
||||
currency.ICN: 3.5,
|
||||
currency.ZRX: 1.9,
|
||||
currency.OMG: 0.4,
|
||||
currency.WTC: 0.5,
|
||||
currency.LRC: 12.3,
|
||||
currency.LLT: 67.8,
|
||||
currency.YOYO: 1,
|
||||
currency.TRX: 1,
|
||||
currency.STRAT: 0.1,
|
||||
currency.SNGLS: 54,
|
||||
currency.BQX: 3.9,
|
||||
currency.KNC: 3.5,
|
||||
currency.SNM: 25,
|
||||
currency.FUN: 86,
|
||||
currency.LINK: 4,
|
||||
currency.XVG: 0.1,
|
||||
currency.CTR: 35,
|
||||
currency.SALT: 2.3,
|
||||
currency.MDA: 2.3,
|
||||
currency.IOTA: 0.5,
|
||||
currency.SUB: 11.4,
|
||||
currency.ETC: 0.01,
|
||||
currency.MTL: 2,
|
||||
currency.MTH: 45,
|
||||
currency.ENG: 2.2,
|
||||
currency.AST: 14.4,
|
||||
currency.DASH: 0.002,
|
||||
currency.BTG: 0.001,
|
||||
currency.EVX: 2.8,
|
||||
currency.REQ: 29.9,
|
||||
currency.VIB: 30,
|
||||
currency.POWR: 8.2,
|
||||
currency.ARK: 0.2,
|
||||
currency.XRP: 0.25,
|
||||
currency.MOD: 2,
|
||||
currency.ENJ: 26,
|
||||
currency.STORJ: 5.1,
|
||||
currency.KMD: 0.002,
|
||||
currency.RCN: 47,
|
||||
currency.NULS: 0.01,
|
||||
currency.RDN: 2.5,
|
||||
currency.XMR: 0.04,
|
||||
currency.DLT: 19.8,
|
||||
currency.AMB: 8.9,
|
||||
currency.BAT: 8,
|
||||
currency.ZEC: 0.005,
|
||||
currency.BCPT: 14.5,
|
||||
currency.ARN: 3,
|
||||
currency.GVT: 0.13,
|
||||
currency.CDT: 81,
|
||||
currency.GXS: 0.3,
|
||||
currency.POE: 134,
|
||||
currency.QSP: 36,
|
||||
currency.BTS: 1,
|
||||
currency.XZC: 0.02,
|
||||
currency.LSK: 0.1,
|
||||
currency.TNT: 47,
|
||||
currency.FUEL: 79,
|
||||
currency.MANA: 18,
|
||||
currency.BCD: 0.01,
|
||||
currency.DGD: 0.04,
|
||||
currency.ADX: 6.3,
|
||||
currency.ADA: 1,
|
||||
currency.PPT: 0.41,
|
||||
currency.CMT: 12,
|
||||
currency.XLM: 0.01,
|
||||
currency.CND: 58,
|
||||
currency.LEND: 84,
|
||||
currency.WABI: 6.6,
|
||||
currency.SBTC: 0.0005,
|
||||
currency.BCX: 0.5,
|
||||
currency.WAVES: 0.002,
|
||||
currency.TNB: 139,
|
||||
currency.GTO: 20,
|
||||
currency.ICX: 0.02,
|
||||
currency.OST: 32,
|
||||
currency.ELF: 3.9,
|
||||
currency.AION: 3.2,
|
||||
currency.CVC: 10.9,
|
||||
currency.REP: 0.2,
|
||||
currency.GNT: 8.9,
|
||||
currency.DATA: 37,
|
||||
currency.ETF: 1,
|
||||
currency.BRD: 3.8,
|
||||
currency.NEBL: 0.01,
|
||||
currency.VIBE: 17.3,
|
||||
currency.LUN: 0.36,
|
||||
currency.CHAT: 60.7,
|
||||
currency.RLC: 3.4,
|
||||
currency.INS: 3.5,
|
||||
currency.IOST: 105.6,
|
||||
currency.STEEM: 0.01,
|
||||
currency.NANO: 0.01,
|
||||
currency.AE: 1.3,
|
||||
currency.VIA: 0.01,
|
||||
currency.BLZ: 10.3,
|
||||
currency.SYS: 1,
|
||||
currency.NCASH: 247.6,
|
||||
currency.POA: 0.01,
|
||||
currency.ONT: 1,
|
||||
currency.ZIL: 37.2,
|
||||
currency.STORM: 152,
|
||||
currency.XEM: 4,
|
||||
currency.WAN: 0.1,
|
||||
currency.WPR: 43.4,
|
||||
currency.QLC: 1,
|
||||
currency.GRS: 0.2,
|
||||
currency.CLOAK: 0.02,
|
||||
currency.LOOM: 11.9,
|
||||
currency.BCN: 1,
|
||||
currency.TUSD: 1.35,
|
||||
currency.ZEN: 0.002,
|
||||
currency.SKY: 0.01,
|
||||
currency.THETA: 24,
|
||||
currency.IOTX: 90.5,
|
||||
currency.QKC: 24.6,
|
||||
currency.AGI: 29.81,
|
||||
currency.NXS: 0.02,
|
||||
currency.SC: 0.1,
|
||||
currency.EON: 10,
|
||||
currency.NPXS: 897,
|
||||
currency.KEY: 223,
|
||||
currency.NAS: 0.1,
|
||||
currency.ADD: 100,
|
||||
currency.MEETONE: 300,
|
||||
currency.ATD: 100,
|
||||
currency.MFT: 175,
|
||||
currency.EOP: 5,
|
||||
currency.DENT: 596,
|
||||
currency.IQ: 50,
|
||||
currency.ARDR: 2,
|
||||
currency.HOT: 1210,
|
||||
currency.VET: 100,
|
||||
currency.DOCK: 68,
|
||||
currency.POLY: 7,
|
||||
currency.VTHO: 21,
|
||||
currency.ONG: 0.1,
|
||||
currency.PHX: 1,
|
||||
currency.HC: 0.005,
|
||||
currency.GO: 0.01,
|
||||
currency.PAX: 1.4,
|
||||
currency.EDO: 1.3,
|
||||
currency.WINGS: 8.9,
|
||||
currency.NAV: 0.2,
|
||||
currency.TRIG: 49.1,
|
||||
currency.APPC: 12.4,
|
||||
currency.PIVX: 0.02,
|
||||
}
|
||||
|
||||
// WithdrawResponse contains status of withdrawal request
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -26,7 +26,7 @@ var lastUpdateID map[string]int64
|
||||
var m sync.Mutex
|
||||
|
||||
// SeedLocalCache seeds depth data
|
||||
func (b *Binance) SeedLocalCache(p pair.CurrencyPair) error {
|
||||
func (b *Binance) SeedLocalCache(p currency.Pair) error {
|
||||
var newOrderBook orderbook.Base
|
||||
|
||||
formattedPair := exchange.FormatExchangeCurrency(b.Name, p)
|
||||
@@ -58,9 +58,7 @@ func (b *Binance) SeedLocalCache(p pair.CurrencyPair) error {
|
||||
orderbook.Item{Amount: Asks.Quantity, Price: Asks.Price})
|
||||
}
|
||||
|
||||
newOrderBook.Pair = pair.NewCurrencyPairFromString(formattedPair.String())
|
||||
newOrderBook.CurrencyPair = formattedPair.String()
|
||||
newOrderBook.LastUpdated = time.Now()
|
||||
newOrderBook.Pair = currency.NewPairFromString(formattedPair.String())
|
||||
newOrderBook.AssetType = ticker.Spot
|
||||
|
||||
return b.Websocket.Orderbook.LoadSnapshot(newOrderBook, b.GetName(), false)
|
||||
@@ -113,7 +111,7 @@ func (b *Binance) UpdateLocalCache(ob WebsocketDepthStream) error {
|
||||
}
|
||||
|
||||
updatedTime := time.Unix(ob.Timestamp, 0)
|
||||
currencyPair := pair.NewCurrencyPairFromString(ob.Pair)
|
||||
currencyPair := currency.NewPairFromString(ob.Pair)
|
||||
|
||||
return b.Websocket.Orderbook.Update(updateBid,
|
||||
updateAsk,
|
||||
@@ -134,16 +132,16 @@ func (b *Binance) WSConnect() error {
|
||||
|
||||
tick := strings.ToLower(
|
||||
strings.Replace(
|
||||
strings.Join(b.EnabledPairs, "@ticker/"), "-", "", -1)) + "@ticker"
|
||||
strings.Join(b.EnabledPairs.Strings(), "@ticker/"), "-", "", -1)) + "@ticker"
|
||||
trade := strings.ToLower(
|
||||
strings.Replace(
|
||||
strings.Join(b.EnabledPairs, "@trade/"), "-", "", -1)) + "@trade"
|
||||
strings.Join(b.EnabledPairs.Strings(), "@trade/"), "-", "", -1)) + "@trade"
|
||||
kline := strings.ToLower(
|
||||
strings.Replace(
|
||||
strings.Join(b.EnabledPairs, "@kline_1m/"), "-", "", -1)) + "@kline_1m"
|
||||
strings.Join(b.EnabledPairs.Strings(), "@kline_1m/"), "-", "", -1)) + "@kline_1m"
|
||||
depth := strings.ToLower(
|
||||
strings.Replace(
|
||||
strings.Join(b.EnabledPairs, "@depth/"), "-", "", -1)) + "@depth"
|
||||
strings.Join(b.EnabledPairs.Strings(), "@depth/"), "-", "", -1)) + "@depth"
|
||||
|
||||
wsurl := b.Websocket.GetWebsocketURL() +
|
||||
"/stream?streams=" +
|
||||
@@ -255,7 +253,7 @@ func (b *Binance) WsHandleData() {
|
||||
}
|
||||
|
||||
b.Websocket.DataHandler <- exchange.TradeData{
|
||||
CurrencyPair: pair.NewCurrencyPairFromString(trade.Symbol),
|
||||
CurrencyPair: currency.NewPairFromString(trade.Symbol),
|
||||
Timestamp: time.Unix(0, trade.TimeStamp),
|
||||
Price: price,
|
||||
Amount: amount,
|
||||
@@ -277,7 +275,7 @@ func (b *Binance) WsHandleData() {
|
||||
var wsTicker exchange.TickerData
|
||||
|
||||
wsTicker.Timestamp = time.Unix(0, t.EventTime)
|
||||
wsTicker.Pair = pair.NewCurrencyPairFromString(t.Symbol)
|
||||
wsTicker.Pair = currency.NewPairFromString(t.Symbol)
|
||||
wsTicker.AssetType = ticker.Spot
|
||||
wsTicker.Exchange = b.GetName()
|
||||
wsTicker.ClosePrice, _ = strconv.ParseFloat(t.CurrDayClose, 64)
|
||||
@@ -301,7 +299,7 @@ func (b *Binance) WsHandleData() {
|
||||
var wsKline exchange.KlineData
|
||||
|
||||
wsKline.Timestamp = time.Unix(0, kline.EventTime)
|
||||
wsKline.Pair = pair.NewCurrencyPairFromString(kline.Symbol)
|
||||
wsKline.Pair = currency.NewPairFromString(kline.Symbol)
|
||||
wsKline.AssetType = ticker.Spot
|
||||
wsKline.Exchange = b.GetName()
|
||||
wsKline.StartTime = time.Unix(0, kline.Kline.StartTime)
|
||||
@@ -332,7 +330,7 @@ func (b *Binance) WsHandleData() {
|
||||
continue
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPairFromString(depth.Pair)
|
||||
currencyPair := currency.NewPairFromString(depth.Pair)
|
||||
|
||||
b.Websocket.DataHandler <- exchange.WebsocketOrderbookUpdate{
|
||||
Pair: currencyPair,
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -44,13 +44,18 @@ func (b *Binance) Run() {
|
||||
log.Errorf("%s Failed to get exchange info.\n", b.GetName())
|
||||
} else {
|
||||
forceUpgrade := false
|
||||
if !common.StringDataContains(b.EnabledPairs, "-") ||
|
||||
!common.StringDataContains(b.AvailablePairs, "-") {
|
||||
if !common.StringDataContains(b.EnabledPairs.Strings(), "-") ||
|
||||
!common.StringDataContains(b.AvailablePairs.Strings(), "-") {
|
||||
forceUpgrade = true
|
||||
}
|
||||
|
||||
if forceUpgrade {
|
||||
enabledPairs := []string{"BTC-USDT"}
|
||||
enabledPairs := currency.Pairs{currency.Pair{
|
||||
Base: currency.BTC,
|
||||
Quote: currency.USDT,
|
||||
Delimiter: "-",
|
||||
}}
|
||||
|
||||
log.Warn("Available pairs for Binance reset due to config upgrade, please enable the ones you would like again")
|
||||
|
||||
err = b.UpdateCurrencies(enabledPairs, true, true)
|
||||
@@ -58,7 +63,14 @@ func (b *Binance) Run() {
|
||||
log.Errorf("%s Failed to get config.\n", b.GetName())
|
||||
}
|
||||
}
|
||||
err = b.UpdateCurrencies(symbols, false, forceUpgrade)
|
||||
|
||||
var newSymbols currency.Pairs
|
||||
for _, p := range symbols {
|
||||
newSymbols = append(newSymbols,
|
||||
currency.NewPairFromString(p))
|
||||
}
|
||||
|
||||
err = b.UpdateCurrencies(newSymbols, false, forceUpgrade)
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to get config.\n", b.GetName())
|
||||
}
|
||||
@@ -66,7 +78,7 @@ func (b *Binance) Run() {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *Binance) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Binance) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
tick, err := b.GetTickers()
|
||||
if err != nil {
|
||||
@@ -86,14 +98,14 @@ func (b *Binance) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Pr
|
||||
tickerPrice.Last = tick[y].LastPrice
|
||||
tickerPrice.Low = tick[y].LowPrice
|
||||
tickerPrice.Volume = tick[y].Volume
|
||||
ticker.ProcessTicker(b.Name, x, tickerPrice, assetType)
|
||||
ticker.ProcessTicker(b.Name, tickerPrice, assetType)
|
||||
}
|
||||
}
|
||||
return ticker.GetTicker(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (b *Binance) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Binance) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tickerNew, err := ticker.GetTicker(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateTicker(p, assetType)
|
||||
@@ -102,8 +114,8 @@ func (b *Binance) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns orderbook base on the currency pair
|
||||
func (b *Binance) GetOrderbookEx(currency pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(b.GetName(), currency, assetType)
|
||||
func (b *Binance) GetOrderbookEx(currency currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(b.GetName(), currency, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateOrderbook(currency, assetType)
|
||||
}
|
||||
@@ -111,7 +123,7 @@ func (b *Binance) GetOrderbookEx(currency pair.CurrencyPair, assetType string) (
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *Binance) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (b *Binance) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
orderbookNew, err := b.GetOrderBook(OrderBookDataRequestParams{Symbol: exchange.FormatExchangeCurrency(b.Name, p).String(), Limit: 1000})
|
||||
if err != nil {
|
||||
@@ -128,8 +140,16 @@ func (b *Binance) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderb
|
||||
orderbook.Item{Amount: asks.Quantity, Price: asks.Price})
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(b.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = b.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetAccountInfo retrieves balances for all enabled currencies for the
|
||||
@@ -154,7 +174,7 @@ func (b *Binance) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
}
|
||||
|
||||
currencyBalance = append(currencyBalance, exchange.AccountCurrencyInfo{
|
||||
CurrencyName: balance.Asset,
|
||||
CurrencyName: currency.NewCode(balance.Asset),
|
||||
TotalValue: freeCurrency + lockedCurrency,
|
||||
Hold: freeCurrency,
|
||||
})
|
||||
@@ -176,13 +196,13 @@ func (b *Binance) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *Binance) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *Binance) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
return resp, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (b *Binance) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
func (b *Binance) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
|
||||
var sideType RequestParamsSideType
|
||||
@@ -204,7 +224,7 @@ func (b *Binance) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orde
|
||||
}
|
||||
|
||||
var orderRequest = NewOrderRequest{
|
||||
Symbol: p.FirstCurrency.String() + p.SecondCurrency.String(),
|
||||
Symbol: p.Base.String() + p.Quote.String(),
|
||||
Side: sideType,
|
||||
Price: price,
|
||||
Quantity: amount,
|
||||
@@ -271,7 +291,7 @@ func (b *Binance) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *Binance) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) (string, error) {
|
||||
func (b *Binance) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) {
|
||||
return b.GetDepositAddressForCurrency(cryptocurrency.String())
|
||||
}
|
||||
|
||||
@@ -313,8 +333,8 @@ func (b *Binance) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
}
|
||||
|
||||
var orders []exchange.OrderDetail
|
||||
for _, currency := range getOrdersRequest.Currencies {
|
||||
resp, err := b.OpenOrders(exchange.FormatExchangeCurrency(b.Name, currency).String())
|
||||
for _, c := range getOrdersRequest.Currencies {
|
||||
resp, err := b.OpenOrders(exchange.FormatExchangeCurrency(b.Name, c).String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -333,7 +353,7 @@ func (b *Binance) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
OrderType: orderType,
|
||||
Price: order.Price,
|
||||
Status: order.Status,
|
||||
CurrencyPair: pair.NewCurrencyPairFromString(order.Symbol),
|
||||
CurrencyPair: currency.NewPairFromString(order.Symbol),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -353,8 +373,8 @@ func (b *Binance) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
}
|
||||
|
||||
var orders []exchange.OrderDetail
|
||||
for _, currency := range getOrdersRequest.Currencies {
|
||||
resp, err := b.AllOrders(exchange.FormatExchangeCurrency(b.Name, currency).String(), "", "1000")
|
||||
for _, c := range getOrdersRequest.Currencies {
|
||||
resp, err := b.AllOrders(exchange.FormatExchangeCurrency(b.Name, c).String(), "", "1000")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -376,7 +396,7 @@ func (b *Binance) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
OrderSide: orderSide,
|
||||
OrderType: orderType,
|
||||
Price: order.Price,
|
||||
CurrencyPair: pair.NewCurrencyPairFromString(order.Symbol),
|
||||
CurrencyPair: currency.NewPairFromString(order.Symbol),
|
||||
Status: order.Status,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -130,9 +130,9 @@ func (b *Bitfinex) Setup(exch config.ExchangeConfig) {
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.Websocket.SetWsStatusAndConnection(exch.Websocket)
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
err := b.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -196,7 +196,8 @@ func (b *Bitfinex) GetLatestSpotPrice(symbol string) (float64, error) {
|
||||
// GetTicker returns ticker information
|
||||
func (b *Bitfinex) GetTicker(symbol string) (Ticker, error) {
|
||||
response := Ticker{}
|
||||
path := common.EncodeURLValues(b.APIUrl+bitfinexAPIVersion+bitfinexTicker+symbol, url.Values{})
|
||||
path := common.EncodeURLValues(b.APIUrl+bitfinexAPIVersion+bitfinexTicker+symbol,
|
||||
url.Values{})
|
||||
|
||||
if err := b.SendHTTPRequest(path, &response, b.Verbose); err != nil {
|
||||
return response, err
|
||||
@@ -214,7 +215,11 @@ func (b *Bitfinex) GetTickerV2(symb string) (Tickerv2, error) {
|
||||
var response []interface{}
|
||||
var tick Tickerv2
|
||||
|
||||
path := fmt.Sprintf("%s/v%s/%s/%s", b.APIUrl, bitfinexAPIVersion2, bitfinexTickerV2, symb)
|
||||
path := fmt.Sprintf("%s/v%s/%s/%s",
|
||||
b.APIUrl,
|
||||
bitfinexAPIVersion2,
|
||||
bitfinexTickerV2,
|
||||
symb)
|
||||
err := b.SendHTTPRequest(path, &response, b.Verbose)
|
||||
if err != nil {
|
||||
return tick, err
|
||||
@@ -464,7 +469,8 @@ func (b *Bitfinex) GetLendbook(symbol string, values url.Values) (Lendbook, erro
|
||||
if len(symbol) == 6 {
|
||||
symbol = symbol[:3]
|
||||
}
|
||||
path := common.EncodeURLValues(b.APIUrl+bitfinexAPIVersion+bitfinexLendbook+symbol, values)
|
||||
path := common.EncodeURLValues(b.APIUrl+bitfinexAPIVersion+bitfinexLendbook+symbol,
|
||||
values)
|
||||
|
||||
return response, b.SendHTTPRequest(path, &response, b.Verbose)
|
||||
}
|
||||
@@ -475,7 +481,8 @@ func (b *Bitfinex) GetLendbook(symbol string, values url.Values) (Lendbook, erro
|
||||
// Symbol - example "USD"
|
||||
func (b *Bitfinex) GetLends(symbol string, values url.Values) ([]Lends, error) {
|
||||
response := []Lends{}
|
||||
path := common.EncodeURLValues(b.APIUrl+bitfinexAPIVersion+bitfinexLends+symbol, values)
|
||||
path := common.EncodeURLValues(b.APIUrl+bitfinexAPIVersion+bitfinexLends+symbol,
|
||||
values)
|
||||
|
||||
return response, b.SendHTTPRequest(path, &response, b.Verbose)
|
||||
}
|
||||
@@ -496,16 +503,19 @@ func (b *Bitfinex) GetSymbolsDetails() ([]SymbolDetails, error) {
|
||||
return response, b.SendHTTPRequest(path, &response, b.Verbose)
|
||||
}
|
||||
|
||||
// GetAccountInformation returns information about your account incl. trading fees
|
||||
// GetAccountInformation returns information about your account incl. trading
|
||||
// fees
|
||||
func (b *Bitfinex) GetAccountInformation() ([]AccountInfo, error) {
|
||||
var responses []AccountInfo
|
||||
return responses, b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexAccountInfo, nil, &responses)
|
||||
return responses, b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexAccountInfo, nil, &responses)
|
||||
}
|
||||
|
||||
// GetAccountFees - Gets all fee rates for all currencies
|
||||
func (b *Bitfinex) GetAccountFees() (AccountFees, error) {
|
||||
response := AccountFees{}
|
||||
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexAccountFees, nil, &response)
|
||||
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexAccountFees, nil, &response)
|
||||
}
|
||||
|
||||
// GetAccountSummary returns a 30-day summary of your trading volume and return
|
||||
@@ -532,7 +542,10 @@ func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (DepositResp
|
||||
req["renew"] = renew
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexDeposit, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexDeposit,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetKeyPermissions checks the permissions of the key being used to generate
|
||||
@@ -541,7 +554,8 @@ func (b *Bitfinex) GetKeyPermissions() (KeyPermissions, error) {
|
||||
response := KeyPermissions{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexKeyPermissions, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexKeyPermissions, nil, &response)
|
||||
}
|
||||
|
||||
// GetMarginInfo shows your trading wallet information for margin trading
|
||||
@@ -549,7 +563,8 @@ func (b *Bitfinex) GetMarginInfo() ([]MarginInfo, error) {
|
||||
response := []MarginInfo{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexMarginInfo, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexMarginInfo, nil, &response)
|
||||
}
|
||||
|
||||
// GetAccountBalance returns full wallet balance information
|
||||
@@ -557,7 +572,8 @@ func (b *Bitfinex) GetAccountBalance() ([]Balance, error) {
|
||||
response := []Balance{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexBalances, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexBalances, nil, &response)
|
||||
}
|
||||
|
||||
// WalletTransfer move available balances between your wallets
|
||||
@@ -574,32 +590,40 @@ func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo
|
||||
req["walletTo"] = walletTo
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexTransfer, req, &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) {
|
||||
func (b *Bitfinex) WithdrawCryptocurrency(withdrawType, wallet, address, paymentID string, amount float64, c currency.Code) ([]Withdrawal, error) {
|
||||
response := []Withdrawal{}
|
||||
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 {
|
||||
if c == currency.XMR {
|
||||
req["paymend_id"] = paymentID
|
||||
}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexWithdrawal, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexWithdrawal,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// WithdrawFIAT requests a withdrawal from one of your wallets.
|
||||
// For Cryptocurrency, use WithdrawCryptocurrency
|
||||
func (b *Bitfinex) WithdrawFIAT(withdrawType, wallet, wireCurrency,
|
||||
accountName, bankName, bankAddress, bankCity, bankCountry, swift, transactionMessage,
|
||||
intermediaryBankName, intermediaryBankAddress, intermediaryBankCity, intermediaryBankCountry, intermediaryBankSwift string,
|
||||
amount, accountNumber, intermediaryBankAccountNumber float64, isExpressWire, requiresIntermediaryBank bool) ([]Withdrawal, error) {
|
||||
accountName, bankName, bankAddress, bankCity, bankCountry, swift,
|
||||
transactionMessage, intermediaryBankName, intermediaryBankAddress,
|
||||
intermediaryBankCity, intermediaryBankCountry, intermediaryBankSwift string,
|
||||
amount, accountNumber, intermediaryBankAccountNumber float64, isExpressWire,
|
||||
requiresIntermediaryBank bool) ([]Withdrawal, error) {
|
||||
response := []Withdrawal{}
|
||||
req := make(map[string]interface{})
|
||||
req["withdraw_type"] = withdrawType
|
||||
@@ -622,12 +646,18 @@ func (b *Bitfinex) WithdrawFIAT(withdrawType, wallet, wireCurrency,
|
||||
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_account"] = strconv.FormatFloat(intermediaryBankAccountNumber,
|
||||
'f',
|
||||
-1,
|
||||
64)
|
||||
req["intermediary_bank_swift"] = intermediaryBankSwift
|
||||
}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexWithdrawal, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexWithdrawal,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// NewOrder submits a new order and returns a order information
|
||||
@@ -649,7 +679,10 @@ func (b *Bitfinex) NewOrder(currencyPair string, amount, price float64, buy bool
|
||||
}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderNew, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOrderNew,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// NewOrderMulti allows several new orders at once
|
||||
@@ -659,7 +692,10 @@ func (b *Bitfinex) NewOrderMulti(orders []PlaceOrder) (OrderMultiResponse, error
|
||||
req["orders"] = orders
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderNewMulti, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOrderNewMulti,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// CancelExistingOrder cancels a single order by OrderID
|
||||
@@ -669,7 +705,10 @@ func (b *Bitfinex) CancelExistingOrder(orderID int64) (Order, error) {
|
||||
req["order_id"] = orderID
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancel, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOrderCancel,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// CancelMultipleOrders cancels multiple orders
|
||||
@@ -679,7 +718,10 @@ func (b *Bitfinex) CancelMultipleOrders(orderIDs []int64) (string, error) {
|
||||
req["order_ids"] = orderIDs
|
||||
|
||||
return response.Result,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancelMulti, req, nil)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOrderCancelMulti,
|
||||
req,
|
||||
nil)
|
||||
}
|
||||
|
||||
// CancelAllExistingOrders cancels all active and open orders
|
||||
@@ -687,7 +729,10 @@ func (b *Bitfinex) CancelAllExistingOrders() (string, error) {
|
||||
response := GenericResponse{}
|
||||
|
||||
return response.Result,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancelAll, nil, nil)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOrderCancelAll,
|
||||
nil,
|
||||
nil)
|
||||
}
|
||||
|
||||
// ReplaceOrder replaces an older order with a new order
|
||||
@@ -709,7 +754,10 @@ func (b *Bitfinex) ReplaceOrder(orderID int64, symbol string, amount, price floa
|
||||
}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderCancelReplace, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOrderCancelReplace,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetOrderStatus returns order status information
|
||||
@@ -719,7 +767,10 @@ func (b *Bitfinex) GetOrderStatus(orderID int64) (Order, error) {
|
||||
req["order_id"] = orderID
|
||||
|
||||
return orderStatus,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderStatus, req, &orderStatus)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOrderStatus,
|
||||
req,
|
||||
&orderStatus)
|
||||
}
|
||||
|
||||
// GetInactiveOrders returns order status information
|
||||
@@ -729,7 +780,10 @@ func (b *Bitfinex) GetInactiveOrders() ([]Order, error) {
|
||||
req["limit"] = "100"
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexInactiveOrders, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexInactiveOrders,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetOpenOrders returns all active orders and statuses
|
||||
@@ -737,7 +791,10 @@ func (b *Bitfinex) GetOpenOrders() ([]Order, error) {
|
||||
var response []Order
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrders, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOrders,
|
||||
nil,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetActivePositions returns an array of active positions
|
||||
@@ -745,7 +802,10 @@ func (b *Bitfinex) GetActivePositions() ([]Position, error) {
|
||||
response := []Position{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexPositions, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexPositions,
|
||||
nil,
|
||||
&response)
|
||||
}
|
||||
|
||||
// ClaimPosition allows positions to be claimed
|
||||
@@ -755,7 +815,10 @@ func (b *Bitfinex) ClaimPosition(positionID int) (Position, error) {
|
||||
req["position_id"] = positionID
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexClaimPosition, nil, nil)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexClaimPosition,
|
||||
nil,
|
||||
nil)
|
||||
}
|
||||
|
||||
// GetBalanceHistory returns balance history for the account
|
||||
@@ -778,7 +841,10 @@ func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince, timeUntil time.Ti
|
||||
}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexHistory, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexHistory,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetMovementHistory returns an array of past deposits and withdrawals
|
||||
@@ -801,7 +867,10 @@ func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUnti
|
||||
}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexHistoryMovements, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexHistoryMovements,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetTradeHistory returns past executed trades
|
||||
@@ -822,7 +891,10 @@ func (b *Bitfinex) GetTradeHistory(currencyPair string, timestamp, until time.Ti
|
||||
}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexTradeHistory, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexTradeHistory,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// NewOffer submits a new offer
|
||||
@@ -836,7 +908,10 @@ func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, d
|
||||
req["direction"] = direction
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOfferNew, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOfferNew,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// CancelOffer cancels offer by offerID
|
||||
@@ -846,7 +921,10 @@ func (b *Bitfinex) CancelOffer(offerID int64) (Offer, error) {
|
||||
req["offer_id"] = offerID
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOfferCancel, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOfferCancel,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetOfferStatus checks offer status whether it has been cancelled, execute or
|
||||
@@ -857,7 +935,10 @@ func (b *Bitfinex) GetOfferStatus(offerID int64) (Offer, error) {
|
||||
req["offer_id"] = offerID
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOrderStatus, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOrderStatus,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetActiveCredits returns all available credits
|
||||
@@ -865,7 +946,10 @@ func (b *Bitfinex) GetActiveCredits() ([]Offer, error) {
|
||||
response := []Offer{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexActiveCredits, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexActiveCredits,
|
||||
nil,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetActiveOffers returns all current active offers
|
||||
@@ -873,7 +957,10 @@ func (b *Bitfinex) GetActiveOffers() ([]Offer, error) {
|
||||
response := []Offer{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexOffers, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexOffers,
|
||||
nil,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetActiveMarginFunding returns an array of active margin funds
|
||||
@@ -881,7 +968,10 @@ func (b *Bitfinex) GetActiveMarginFunding() ([]MarginFunds, error) {
|
||||
response := []MarginFunds{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexMarginActiveFunds, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexMarginActiveFunds,
|
||||
nil,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetUnusedMarginFunds returns an array of funding borrowed but not currently
|
||||
@@ -890,7 +980,10 @@ func (b *Bitfinex) GetUnusedMarginFunds() ([]MarginFunds, error) {
|
||||
response := []MarginFunds{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexMarginUnusedFunds, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexMarginUnusedFunds,
|
||||
nil,
|
||||
&response)
|
||||
}
|
||||
|
||||
// GetMarginTotalTakenFunds returns an array of active funding used in a
|
||||
@@ -899,7 +992,10 @@ func (b *Bitfinex) GetMarginTotalTakenFunds() ([]MarginTotalTakenFunds, error) {
|
||||
response := []MarginTotalTakenFunds{}
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexMarginTotalFunds, nil, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexMarginTotalFunds,
|
||||
nil,
|
||||
&response)
|
||||
}
|
||||
|
||||
// CloseMarginFunding closes an unused or used taken fund
|
||||
@@ -909,7 +1005,10 @@ func (b *Bitfinex) CloseMarginFunding(swapID int64) (Offer, error) {
|
||||
req["swap_id"] = swapID
|
||||
|
||||
return response,
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost, bitfinexMarginClose, req, &response)
|
||||
b.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
bitfinexMarginClose,
|
||||
req,
|
||||
&response)
|
||||
}
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated request
|
||||
@@ -921,7 +1020,8 @@ func (b *Bitfinex) SendHTTPRequest(path string, result interface{}, verbose bool
|
||||
// unmarshals result to a supplied variable
|
||||
func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[string]interface{}, result interface{}) error {
|
||||
if !b.AuthenticatedAPISupport {
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name)
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet,
|
||||
b.Name)
|
||||
}
|
||||
|
||||
if b.Nonce.Get() == 0 {
|
||||
@@ -948,13 +1048,20 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[
|
||||
}
|
||||
|
||||
PayloadBase64 := common.Base64Encode(PayloadJSON)
|
||||
hmac := common.GetHMAC(common.HashSHA512_384, []byte(PayloadBase64), []byte(b.APISecret))
|
||||
hmac := common.GetHMAC(common.HashSHA512_384, []byte(PayloadBase64),
|
||||
[]byte(b.APISecret))
|
||||
headers := make(map[string]string)
|
||||
headers["X-BFX-APIKEY"] = b.APIKey
|
||||
headers["X-BFX-PAYLOAD"] = PayloadBase64
|
||||
headers["X-BFX-SIGNATURE"] = common.HexEncodeToString(hmac)
|
||||
|
||||
return b.SendPayload(method, b.APIUrl+bitfinexAPIVersion+path, headers, nil, result, true, b.Verbose)
|
||||
return b.SendPayload(method,
|
||||
b.APIUrl+bitfinexAPIVersion+path,
|
||||
headers,
|
||||
nil,
|
||||
result,
|
||||
true,
|
||||
b.Verbose)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
@@ -967,7 +1074,11 @@ func (b *Bitfinex) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
fee, err = b.CalculateTradingFee(accountInfos, feeBuilder.PurchasePrice, feeBuilder.Amount, feeBuilder.FirstCurrency, feeBuilder.IsMaker)
|
||||
fee, err = b.CalculateTradingFee(accountInfos,
|
||||
feeBuilder.PurchasePrice,
|
||||
feeBuilder.Amount,
|
||||
feeBuilder.Pair.Base,
|
||||
feeBuilder.IsMaker)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -979,7 +1090,8 @@ func (b *Bitfinex) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
fee, err = b.GetCryptocurrencyWithdrawalFee(feeBuilder.FirstCurrency, accountFees)
|
||||
fee, err = b.GetCryptocurrencyWithdrawalFee(feeBuilder.Pair.Base,
|
||||
accountFees)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -995,8 +1107,8 @@ 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 result := accountFees.Withdraw[currency].(type) {
|
||||
func (b *Bitfinex) GetCryptocurrencyWithdrawalFee(c currency.Code, accountFees AccountFees) (fee float64, err error) {
|
||||
switch result := accountFees.Withdraw[c.String()].(type) {
|
||||
case string:
|
||||
fee, err = strconv.ParseFloat(result, 64)
|
||||
if err != nil {
|
||||
@@ -1018,10 +1130,10 @@ func getInternationalBankWithdrawalFee(amount float64) float64 {
|
||||
}
|
||||
|
||||
// CalculateTradingFee returns an estimate of fee based on type of whether is maker or taker fee
|
||||
func (b *Bitfinex) CalculateTradingFee(accountInfos []AccountInfo, purchasePrice, amount float64, currency string, isMaker bool) (fee float64, err error) {
|
||||
func (b *Bitfinex) CalculateTradingFee(accountInfos []AccountInfo, purchasePrice, amount float64, c currency.Code, isMaker bool) (fee float64, err error) {
|
||||
for _, i := range accountInfos {
|
||||
for _, j := range i.Fees {
|
||||
if currency == j.Pairs {
|
||||
if c.String() == j.Pairs {
|
||||
if isMaker {
|
||||
fee = j.MakerFees
|
||||
} else {
|
||||
@@ -1038,77 +1150,75 @@ func (b *Bitfinex) CalculateTradingFee(accountInfos []AccountInfo, purchasePrice
|
||||
}
|
||||
|
||||
// ConvertSymbolToWithdrawalType You need to have specific withdrawal types to withdraw from Bitfinex
|
||||
func (b *Bitfinex) ConvertSymbolToWithdrawalType(currency string) string {
|
||||
switch currency {
|
||||
case symbol.BTC:
|
||||
func (b *Bitfinex) ConvertSymbolToWithdrawalType(c currency.Code) string {
|
||||
switch c {
|
||||
case currency.BTC:
|
||||
return "bitcoin"
|
||||
case symbol.LTC:
|
||||
case currency.LTC:
|
||||
return "litecoin"
|
||||
case symbol.ETH:
|
||||
case currency.ETH:
|
||||
return "ethereum"
|
||||
case symbol.ETC:
|
||||
case currency.ETC:
|
||||
return "ethereumc"
|
||||
case symbol.USDT:
|
||||
case currency.USDT:
|
||||
return "tetheruso"
|
||||
case "Wire":
|
||||
return "wire"
|
||||
case symbol.ZEC:
|
||||
case currency.ZEC:
|
||||
return "zcash"
|
||||
case symbol.XMR:
|
||||
case currency.XMR:
|
||||
return "monero"
|
||||
case symbol.DSH:
|
||||
case currency.DSH:
|
||||
return "dash"
|
||||
case symbol.XRP:
|
||||
case currency.XRP:
|
||||
return "ripple"
|
||||
case symbol.SAN:
|
||||
case currency.SAN:
|
||||
return "santiment"
|
||||
case symbol.OMG:
|
||||
case currency.OMG:
|
||||
return "omisego"
|
||||
case symbol.BCH:
|
||||
case currency.BCH:
|
||||
return "bcash"
|
||||
case symbol.ETP:
|
||||
case currency.ETP:
|
||||
return "metaverse"
|
||||
case symbol.AVT:
|
||||
case currency.AVT:
|
||||
return "aventus"
|
||||
case symbol.EDO:
|
||||
case currency.EDO:
|
||||
return "eidoo"
|
||||
case symbol.BTG:
|
||||
case currency.BTG:
|
||||
return "bgold"
|
||||
case symbol.DATA:
|
||||
case currency.DATA:
|
||||
return "datacoin"
|
||||
case symbol.GNT:
|
||||
case currency.GNT:
|
||||
return "golem"
|
||||
case symbol.SNT:
|
||||
case currency.SNT:
|
||||
return "status"
|
||||
default:
|
||||
return common.StringToLower(currency)
|
||||
return c.Lower().String()
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertSymbolToDepositMethod returns a converted currency deposit method
|
||||
func (b *Bitfinex) ConvertSymbolToDepositMethod(currency string) (method string, err error) {
|
||||
switch currency {
|
||||
case symbol.BTC:
|
||||
func (b *Bitfinex) ConvertSymbolToDepositMethod(c currency.Code) (method string, err error) {
|
||||
switch c {
|
||||
case currency.BTC:
|
||||
method = "bitcoin"
|
||||
case symbol.LTC:
|
||||
case currency.LTC:
|
||||
method = "litecoin"
|
||||
case symbol.ETH:
|
||||
case currency.ETH:
|
||||
method = "ethereum"
|
||||
case symbol.ETC:
|
||||
case currency.ETC:
|
||||
method = "ethereumc"
|
||||
case symbol.USDT:
|
||||
case currency.USDT:
|
||||
method = "tetheruso"
|
||||
case symbol.ZEC:
|
||||
case currency.ZEC:
|
||||
method = "zcash"
|
||||
case symbol.XMR:
|
||||
case currency.XMR:
|
||||
method = "monero"
|
||||
case symbol.BCH:
|
||||
case currency.BCH:
|
||||
method = "bcash"
|
||||
case symbol.MIOTA:
|
||||
case currency.MIOTA:
|
||||
method = "iota"
|
||||
default:
|
||||
err = fmt.Errorf("currency %s not supported in method list",
|
||||
currency)
|
||||
c)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -613,13 +612,10 @@ func TestCloseMarginFunding(t *testing.T) {
|
||||
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -680,7 +676,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.001) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.001), resp)
|
||||
t.Error(err)
|
||||
@@ -689,7 +685,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.001) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.001), resp)
|
||||
t.Error(err)
|
||||
@@ -756,10 +752,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "",
|
||||
FirstCurrency: symbol.LTC,
|
||||
SecondCurrency: symbol.BTC,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "",
|
||||
Base: currency.LTC,
|
||||
Quote: currency.BTC,
|
||||
}
|
||||
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -777,7 +773,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -803,7 +799,7 @@ func TestCancelAllExchangeOrdera(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -842,7 +838,7 @@ func TestWithdraw(t *testing.T) {
|
||||
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.BTC,
|
||||
Currency: currency.BTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
@@ -866,7 +862,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.BTC,
|
||||
Currency: currency.BTC,
|
||||
Description: "WITHDRAW IT ALL",
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
@@ -874,7 +870,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "Hyrule",
|
||||
BankName: "Federal Reserve Bank",
|
||||
WireCurrency: symbol.USD,
|
||||
WireCurrency: currency.USD.String(),
|
||||
SwiftCode: "Taylor",
|
||||
RequiresIntermediaryBank: false,
|
||||
IsExpressWire: false,
|
||||
@@ -899,7 +895,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.BTC,
|
||||
Currency: currency.BTC,
|
||||
Description: "WITHDRAW IT ALL",
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
@@ -907,7 +903,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "Hyrule",
|
||||
BankName: "Federal Reserve Bank",
|
||||
WireCurrency: symbol.USD,
|
||||
WireCurrency: currency.USD.String(),
|
||||
SwiftCode: "Taylor",
|
||||
RequiresIntermediaryBank: true,
|
||||
IsExpressWire: false,
|
||||
@@ -930,12 +926,12 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if areTestAPIKeysSet() {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "deposit")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "deposit")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "deposit")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "deposit")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
@@ -171,7 +171,7 @@ func (b *Bitfinex) WsConnect() error {
|
||||
if x == "book" {
|
||||
params["prec"] = "P0"
|
||||
}
|
||||
params["pair"] = y
|
||||
params["pair"] = y.String()
|
||||
err = b.WsSubscribe(x, params)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -306,7 +306,7 @@ func (b *Bitfinex) WsDataHandler() {
|
||||
}
|
||||
|
||||
if len(newOrderbook) > 1 {
|
||||
err := b.WsInsertSnapshot(pair.NewCurrencyPairFromString(chanInfo.Pair),
|
||||
err := b.WsInsertSnapshot(currency.NewPairFromString(chanInfo.Pair),
|
||||
"SPOT",
|
||||
newOrderbook)
|
||||
|
||||
@@ -317,7 +317,7 @@ func (b *Bitfinex) WsDataHandler() {
|
||||
continue
|
||||
}
|
||||
|
||||
err := b.WsUpdateOrderbook(pair.NewCurrencyPairFromString(chanInfo.Pair),
|
||||
err := b.WsUpdateOrderbook(currency.NewPairFromString(chanInfo.Pair),
|
||||
"SPOT",
|
||||
newOrderbook[0])
|
||||
|
||||
@@ -332,7 +332,7 @@ func (b *Bitfinex) WsDataHandler() {
|
||||
ClosePrice: chanData[7].(float64),
|
||||
HighPrice: chanData[9].(float64),
|
||||
LowPrice: chanData[10].(float64),
|
||||
Pair: pair.NewCurrencyPairFromString(chanInfo.Pair),
|
||||
Pair: currency.NewPairFromString(chanInfo.Pair),
|
||||
Exchange: b.GetName(),
|
||||
AssetType: "SPOT",
|
||||
}
|
||||
@@ -485,7 +485,7 @@ func (b *Bitfinex) WsDataHandler() {
|
||||
}
|
||||
|
||||
b.Websocket.DataHandler <- exchange.TradeData{
|
||||
CurrencyPair: pair.NewCurrencyPairFromString(chanInfo.Pair),
|
||||
CurrencyPair: currency.NewPairFromString(chanInfo.Pair),
|
||||
Timestamp: time.Unix(trades[0].Timestamp, 0),
|
||||
Price: trades[0].Price,
|
||||
Amount: newAmount,
|
||||
@@ -504,7 +504,7 @@ func (b *Bitfinex) WsDataHandler() {
|
||||
|
||||
// WsInsertSnapshot add the initial orderbook snapshot when subscribed to a
|
||||
// channel
|
||||
func (b *Bitfinex) WsInsertSnapshot(p pair.CurrencyPair, assetType string, books []WebsocketBook) error {
|
||||
func (b *Bitfinex) WsInsertSnapshot(p currency.Pair, assetType string, books []WebsocketBook) error {
|
||||
if len(books) == 0 {
|
||||
return errors.New("bitfinex.go error - no orderbooks submitted")
|
||||
}
|
||||
@@ -526,8 +526,6 @@ func (b *Bitfinex) WsInsertSnapshot(p pair.CurrencyPair, assetType string, books
|
||||
newOrderbook.Asks = ask
|
||||
newOrderbook.AssetType = assetType
|
||||
newOrderbook.Bids = bid
|
||||
newOrderbook.CurrencyPair = p.Pair().String()
|
||||
newOrderbook.LastUpdated = time.Now()
|
||||
newOrderbook.Pair = p
|
||||
|
||||
err := b.Websocket.Orderbook.LoadSnapshot(newOrderbook, b.GetName(), false)
|
||||
@@ -543,7 +541,7 @@ func (b *Bitfinex) WsInsertSnapshot(p pair.CurrencyPair, assetType string, books
|
||||
|
||||
// WsUpdateOrderbook updates the orderbook list, removing and adding to the
|
||||
// orderbook sides
|
||||
func (b *Bitfinex) WsUpdateOrderbook(p pair.CurrencyPair, assetType string, book WebsocketBook) error {
|
||||
func (b *Bitfinex) WsUpdateOrderbook(p currency.Pair, assetType string, book WebsocketBook) error {
|
||||
|
||||
if book.Count > 0 {
|
||||
if book.Amount > 0 {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -38,7 +38,13 @@ func (b *Bitfinex) Run() {
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to get available symbols.\n", b.GetName())
|
||||
} else {
|
||||
err = b.UpdateCurrencies(exchangeProducts, false, false)
|
||||
var newExchangeProducts currency.Pairs
|
||||
for _, p := range exchangeProducts {
|
||||
newExchangeProducts = append(newExchangeProducts,
|
||||
currency.NewPairFromString(p))
|
||||
}
|
||||
|
||||
err = b.UpdateCurrencies(newExchangeProducts, false, false)
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to update available symbols.\n", b.GetName())
|
||||
}
|
||||
@@ -46,13 +52,13 @@ func (b *Bitfinex) Run() {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *Bitfinex) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bitfinex) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
enabledPairs := b.GetEnabledCurrencies()
|
||||
|
||||
var pairs []string
|
||||
for x := range enabledPairs {
|
||||
pairs = append(pairs, "t"+enabledPairs[x].Pair().String())
|
||||
pairs = append(pairs, "t"+enabledPairs[x].String())
|
||||
}
|
||||
|
||||
tickerNew, err := b.GetTickersV2(common.JoinStrings(pairs, ","))
|
||||
@@ -61,7 +67,9 @@ func (b *Bitfinex) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.P
|
||||
}
|
||||
|
||||
for x := range tickerNew {
|
||||
newP := pair.NewCurrencyPair(tickerNew[x].Symbol[1:4], tickerNew[x].Symbol[4:])
|
||||
newP := currency.NewPairFromStrings(tickerNew[x].Symbol[1:4],
|
||||
tickerNew[x].Symbol[4:])
|
||||
|
||||
var tick ticker.Price
|
||||
tick.Pair = newP
|
||||
tick.Ask = tickerNew[x].Ask
|
||||
@@ -70,13 +78,17 @@ func (b *Bitfinex) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.P
|
||||
tick.Last = tickerNew[x].Last
|
||||
tick.Volume = tickerNew[x].Volume
|
||||
tick.High = tickerNew[x].High
|
||||
ticker.ProcessTicker(b.Name, tick.Pair, tick, assetType)
|
||||
|
||||
err = ticker.ProcessTicker(b.Name, tick, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
}
|
||||
return ticker.GetTicker(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (b *Bitfinex) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bitfinex) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tick, err := ticker.GetTicker(b.GetName(), p, ticker.Spot)
|
||||
if err != nil {
|
||||
return b.UpdateTicker(p, assetType)
|
||||
@@ -85,8 +97,8 @@ func (b *Bitfinex) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns the orderbook for a currency pair
|
||||
func (b *Bitfinex) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
|
||||
func (b *Bitfinex) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateOrderbook(p, assetType)
|
||||
}
|
||||
@@ -94,26 +106,38 @@ func (b *Bitfinex) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderb
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *Bitfinex) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (b *Bitfinex) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
urlVals := url.Values{}
|
||||
urlVals.Set("limit_bids", "100")
|
||||
urlVals.Set("limit_asks", "100")
|
||||
orderbookNew, err := b.GetOrderbook(p.Pair().String(), urlVals)
|
||||
orderbookNew, err := b.GetOrderbook(p.String(), urlVals)
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
for x := range orderbookNew.Asks {
|
||||
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Price: orderbookNew.Asks[x].Price, Amount: orderbookNew.Asks[x].Amount})
|
||||
orderBook.Asks = append(orderBook.Asks,
|
||||
orderbook.Item{Price: orderbookNew.Asks[x].Price,
|
||||
Amount: orderbookNew.Asks[x].Amount})
|
||||
}
|
||||
|
||||
for x := range orderbookNew.Bids {
|
||||
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Price: orderbookNew.Bids[x].Price, Amount: orderbookNew.Bids[x].Amount})
|
||||
orderBook.Bids = append(orderBook.Bids,
|
||||
orderbook.Item{Price: orderbookNew.Bids[x].Price,
|
||||
Amount: orderbookNew.Bids[x].Amount})
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(b.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = b.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetAccountInfo retrieves balances for all enabled currencies on the
|
||||
@@ -137,7 +161,7 @@ func (b *Bitfinex) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
if Accounts[i].ID == bal.Type {
|
||||
Accounts[i].Currencies = append(Accounts[i].Currencies,
|
||||
exchange.AccountCurrencyInfo{
|
||||
CurrencyName: bal.Currency,
|
||||
CurrencyName: currency.NewCode(bal.Currency),
|
||||
TotalValue: bal.Amount,
|
||||
Hold: bal.Amount - bal.Available,
|
||||
})
|
||||
@@ -157,14 +181,14 @@ func (b *Bitfinex) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *Bitfinex) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *Bitfinex) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (b *Bitfinex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
func (b *Bitfinex) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
var isBuying bool
|
||||
|
||||
@@ -172,7 +196,12 @@ func (b *Bitfinex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, ord
|
||||
isBuying = true
|
||||
}
|
||||
|
||||
response, err := b.NewOrder(p.Pair().String(), amount, price, isBuying, orderType.ToString(), false)
|
||||
response, err := b.NewOrder(p.String(),
|
||||
amount,
|
||||
price,
|
||||
isBuying,
|
||||
orderType.ToString(),
|
||||
false)
|
||||
|
||||
if response.OrderID > 0 {
|
||||
submitOrderResponse.OrderID = fmt.Sprintf("%v", response.OrderID)
|
||||
@@ -217,8 +246,8 @@ func (b *Bitfinex) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *Bitfinex) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
|
||||
method, err := b.ConvertSymbolToDepositMethod(cryptocurrency.String())
|
||||
func (b *Bitfinex) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) {
|
||||
method, err := b.ConvertSymbolToDepositMethod(cryptocurrency)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -233,12 +262,17 @@ func (b *Bitfinex) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID
|
||||
|
||||
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted
|
||||
func (b *Bitfinex) WithdrawCryptocurrencyFunds(withdrawRequest exchange.WithdrawRequest) (string, error) {
|
||||
withdrawalType := b.ConvertSymbolToWithdrawalType(withdrawRequest.Currency.String())
|
||||
withdrawalType := b.ConvertSymbolToWithdrawalType(withdrawRequest.Currency)
|
||||
// Bitfinex has support for three types, exchange, margin and deposit
|
||||
// As this is for trading, I've made the wrapper default 'exchange'
|
||||
// TODO: Discover an automated way to make the decision for wallet type to withdraw from
|
||||
walletType := "exchange"
|
||||
resp, err := b.WithdrawCryptocurrency(withdrawalType, walletType, withdrawRequest.Address, withdrawRequest.Currency.String(), withdrawRequest.Description, withdrawRequest.Amount)
|
||||
resp, err := b.WithdrawCryptocurrency(withdrawalType,
|
||||
walletType,
|
||||
withdrawRequest.Address,
|
||||
withdrawRequest.Description,
|
||||
withdrawRequest.Amount,
|
||||
withdrawRequest.Currency)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -328,7 +362,7 @@ func (b *Bitfinex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) (
|
||||
OrderSide: orderSide,
|
||||
Price: order.Price,
|
||||
RemainingAmount: order.RemainingAmount,
|
||||
CurrencyPair: pair.NewCurrencyPairFromString(order.Symbol),
|
||||
CurrencyPair: currency.NewPairFromString(order.Symbol),
|
||||
ExecutedAmount: order.ExecutedAmount,
|
||||
}
|
||||
|
||||
@@ -389,7 +423,7 @@ func (b *Bitfinex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) (
|
||||
Price: order.Price,
|
||||
RemainingAmount: order.RemainingAmount,
|
||||
ExecutedAmount: order.ExecutedAmount,
|
||||
CurrencyPair: pair.NewCurrencyPairFromString(order.Symbol),
|
||||
CurrencyPair: currency.NewPairFromString(order.Symbol),
|
||||
}
|
||||
|
||||
switch {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -115,9 +115,9 @@ func (b *Bitflyer) Setup(exch config.ExchangeConfig) {
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.Websocket.SetWsStatusAndConnection(exch.Websocket)
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
err := b.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -400,9 +400,9 @@ func (b *Bitflyer) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
case exchange.CryptocurrencyTradeFee:
|
||||
fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount)
|
||||
case exchange.InternationalBankDepositFee:
|
||||
fee = getDepositFee(feeBuilder.BankTransactionType, feeBuilder.CurrencyItem)
|
||||
fee = getDepositFee(feeBuilder.BankTransactionType, feeBuilder.FiatCurrency)
|
||||
case exchange.InternationalBankWithdrawalFee:
|
||||
fee = getWithdrawalFee(feeBuilder.BankTransactionType, feeBuilder.CurrencyItem, feeBuilder.Amount)
|
||||
fee = getWithdrawalFee(feeBuilder.BankTransactionType, feeBuilder.FiatCurrency, feeBuilder.Amount)
|
||||
}
|
||||
if fee < 0 {
|
||||
fee = 0
|
||||
@@ -417,16 +417,18 @@ func calculateTradingFee(purchasePrice, amount float64) float64 {
|
||||
return fee * amount * purchasePrice
|
||||
}
|
||||
|
||||
func getDepositFee(bankTransactionType exchange.InternationalBankTransactionType, currency string) (fee float64) {
|
||||
if bankTransactionType == exchange.WireTransfer && currency == symbol.JPY {
|
||||
fee = 324
|
||||
func getDepositFee(bankTransactionType exchange.InternationalBankTransactionType, c currency.Code) (fee float64) {
|
||||
if bankTransactionType == exchange.WireTransfer {
|
||||
if c.Item == currency.JPY.Item {
|
||||
fee = 324
|
||||
}
|
||||
}
|
||||
return fee
|
||||
}
|
||||
|
||||
func getWithdrawalFee(bankTransactionType exchange.InternationalBankTransactionType, currency string, amount float64) (fee float64) {
|
||||
func getWithdrawalFee(bankTransactionType exchange.InternationalBankTransactionType, c currency.Code, amount float64) (fee float64) {
|
||||
if bankTransactionType == exchange.WireTransfer {
|
||||
if currency == symbol.JPY {
|
||||
if c.Item == currency.JPY.Item {
|
||||
if amount < 30000 {
|
||||
fee = 540
|
||||
} else {
|
||||
|
||||
@@ -6,8 +6,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -124,20 +123,20 @@ func TestGetExchangeStatus(t *testing.T) {
|
||||
|
||||
func TestCheckFXString(t *testing.T) {
|
||||
t.Parallel()
|
||||
p := pair.NewCurrencyPairDelimiter("FXBTC_JPY", "_")
|
||||
p := currency.NewPairDelimiter("FXBTC_JPY", "_")
|
||||
p = b.CheckFXString(p)
|
||||
if p.FirstCurrency.String() != "FX_BTC" {
|
||||
if p.Base.String() != "FX_BTC" {
|
||||
t.Error("test failed - Bitflyer - CheckFXString() error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTickerPrice(t *testing.T) {
|
||||
t.Parallel()
|
||||
var p pair.CurrencyPair
|
||||
var p currency.Pair
|
||||
|
||||
currencies := b.GetAvailableCurrencies()
|
||||
for _, pair := range currencies {
|
||||
if pair.Pair().String() == "FXBTC_JPY" {
|
||||
if pair.String() == "FXBTC_JPY" {
|
||||
p = pair
|
||||
break
|
||||
}
|
||||
@@ -152,13 +151,10 @@ func TestGetTickerPrice(t *testing.T) {
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
CurrencyItem: symbol.JPY,
|
||||
FiatCurrency: currency.JPY,
|
||||
BankTransactionType: exchange.WireTransfer,
|
||||
}
|
||||
}
|
||||
@@ -220,7 +216,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.JPY
|
||||
feeBuilder.FiatCurrency = currency.JPY
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(324) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(324), resp)
|
||||
t.Error(err)
|
||||
@@ -229,7 +225,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.JPY
|
||||
feeBuilder.FiatCurrency = currency.JPY
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(540) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(540), resp)
|
||||
t.Error(err)
|
||||
@@ -295,10 +291,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "",
|
||||
FirstCurrency: symbol.LTC,
|
||||
SecondCurrency: symbol.BTC,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "",
|
||||
Base: currency.LTC,
|
||||
Quote: currency.BTC,
|
||||
}
|
||||
_, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if err != common.ErrNotYetImplemented {
|
||||
@@ -314,7 +310,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
@@ -337,7 +333,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
@@ -357,7 +353,7 @@ func TestWithdraw(t *testing.T) {
|
||||
TestSetup(t)
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.BTC,
|
||||
Currency: currency.BTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -49,12 +49,12 @@ func (b *Bitflyer) Run() {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *Bitflyer) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bitflyer) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
|
||||
p = b.CheckFXString(p)
|
||||
|
||||
tickerNew, err := b.GetTicker(p.Pair().String())
|
||||
tickerNew, err := b.GetTicker(p.String())
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
@@ -66,12 +66,16 @@ func (b *Bitflyer) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.P
|
||||
tickerPrice.Last = tickerNew.Last
|
||||
tickerPrice.Volume = tickerNew.Volume
|
||||
// tickerPrice.High
|
||||
ticker.ProcessTicker(b.GetName(), p, tickerPrice, assetType)
|
||||
err = ticker.ProcessTicker(b.GetName(), tickerPrice, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
|
||||
return ticker.GetTicker(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (b *Bitflyer) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bitflyer) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tick, err := ticker.GetTicker(b.GetName(), p, ticker.Spot)
|
||||
if err != nil {
|
||||
return b.UpdateTicker(p, assetType)
|
||||
@@ -80,17 +84,17 @@ func (b *Bitflyer) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker
|
||||
}
|
||||
|
||||
// CheckFXString upgrades currency pair if needed
|
||||
func (b *Bitflyer) CheckFXString(p pair.CurrencyPair) pair.CurrencyPair {
|
||||
if common.StringContains(p.FirstCurrency.String(), "FX") {
|
||||
p.FirstCurrency = "FX_BTC"
|
||||
func (b *Bitflyer) CheckFXString(p currency.Pair) currency.Pair {
|
||||
if common.StringContains(p.Base.String(), "FX") {
|
||||
p.Base = currency.FX_BTC
|
||||
return p
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns the orderbook for a currency pair
|
||||
func (b *Bitflyer) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
|
||||
func (b *Bitflyer) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateOrderbook(p, assetType)
|
||||
}
|
||||
@@ -98,12 +102,12 @@ func (b *Bitflyer) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderb
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *Bitflyer) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (b *Bitflyer) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
|
||||
p = b.CheckFXString(p)
|
||||
|
||||
orderbookNew, err := b.GetOrderBook(p.Pair().String())
|
||||
orderbookNew, err := b.GetOrderBook(p.String())
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
@@ -116,8 +120,16 @@ func (b *Bitflyer) UpdateOrderbook(p pair.CurrencyPair, assetType string) (order
|
||||
orderBook.Bids = append(orderBook.Bids, orderbook.Item{Price: orderbookNew.Bids[x].Price, Amount: orderbookNew.Bids[x].Size})
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(b.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = b.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetAccountInfo retrieves balances for all enabled currencies on the
|
||||
@@ -146,14 +158,14 @@ func (b *Bitflyer) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *Bitflyer) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *Bitflyer) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (b *Bitflyer) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
|
||||
func (b *Bitflyer) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
|
||||
return submitOrderResponse, common.ErrNotYetImplemented
|
||||
@@ -184,7 +196,7 @@ func (b *Bitflyer) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *Bitflyer) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
|
||||
func (b *Bitflyer) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) {
|
||||
return "", common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -97,9 +97,9 @@ func (b *Bithumb) Setup(exch config.ExchangeConfig) {
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.Websocket.SetWsStatusAndConnection(exch.Websocket)
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
err := b.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -614,11 +614,11 @@ func (b *Bithumb) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
case exchange.CryptocurrencyTradeFee:
|
||||
fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount)
|
||||
case exchange.CyptocurrencyDepositFee:
|
||||
fee = getDepositFee(feeBuilder.FirstCurrency, feeBuilder.Amount)
|
||||
fee = getDepositFee(feeBuilder.Pair.Base, feeBuilder.Amount)
|
||||
case exchange.CryptocurrencyWithdrawalFee:
|
||||
fee = getWithdrawalFee(feeBuilder.FirstCurrency)
|
||||
fee = getWithdrawalFee(feeBuilder.Pair.Base)
|
||||
case exchange.InternationalBankWithdrawalFee:
|
||||
fee = getWithdrawalFee(feeBuilder.CurrencyItem)
|
||||
fee = getWithdrawalFee(feeBuilder.FiatCurrency)
|
||||
}
|
||||
if fee < 0 {
|
||||
fee = 0
|
||||
@@ -633,31 +633,31 @@ func calculateTradingFee(purchasePrice, amount float64) float64 {
|
||||
}
|
||||
|
||||
// getDepositFee returns fee on a currency when depositing small amounts to bithumb
|
||||
func getDepositFee(currency string, amount float64) float64 {
|
||||
func getDepositFee(c currency.Code, amount float64) float64 {
|
||||
var fee float64
|
||||
|
||||
switch currency {
|
||||
case symbol.BTC:
|
||||
switch c {
|
||||
case currency.BTC:
|
||||
if amount <= 0.005 {
|
||||
fee = 0.001
|
||||
}
|
||||
case symbol.LTC:
|
||||
case currency.LTC:
|
||||
if amount <= 0.3 {
|
||||
fee = 0.01
|
||||
}
|
||||
case symbol.DASH:
|
||||
case currency.DASH:
|
||||
if amount <= 0.04 {
|
||||
fee = 0.01
|
||||
}
|
||||
case symbol.BCH:
|
||||
case currency.BCH:
|
||||
if amount <= 0.03 {
|
||||
fee = 0.001
|
||||
}
|
||||
case symbol.ZEC:
|
||||
case currency.ZEC:
|
||||
if amount <= 0.02 {
|
||||
fee = 0.001
|
||||
}
|
||||
case symbol.BTG:
|
||||
case currency.BTG:
|
||||
if amount <= 0.15 {
|
||||
fee = 0.001
|
||||
}
|
||||
@@ -667,8 +667,8 @@ func getDepositFee(currency string, amount float64) float64 {
|
||||
}
|
||||
|
||||
// getWithdrawalFee returns fee on a currency when withdrawing out of bithumb
|
||||
func getWithdrawalFee(currency string) float64 {
|
||||
return WithdrawalFees[currency]
|
||||
func getWithdrawalFee(c currency.Code) float64 {
|
||||
return WithdrawalFees[c]
|
||||
}
|
||||
|
||||
var errCode = map[string]string{
|
||||
|
||||
@@ -5,8 +5,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -195,13 +194,10 @@ func TestMarketSellOrder(t *testing.T) {
|
||||
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +256,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -269,7 +265,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -338,10 +334,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "",
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.LTC,
|
||||
}
|
||||
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -359,7 +355,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -385,7 +381,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -424,12 +420,12 @@ func TestGetAccountInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestModifyOrder(t *testing.T) {
|
||||
curr := pair.NewCurrencyPairFromString("BTCUSD")
|
||||
curr := currency.NewPairFromString("BTCUSD")
|
||||
_, err := b.ModifyOrder(exchange.ModifyOrder{OrderID: "1337",
|
||||
Price: 100,
|
||||
Amount: 1000,
|
||||
OrderSide: exchange.SellOrderSide,
|
||||
Currency: curr})
|
||||
Price: 100,
|
||||
Amount: 1000,
|
||||
OrderSide: exchange.SellOrderSide,
|
||||
CurrencyPair: curr})
|
||||
if err == nil {
|
||||
t.Error("Test Failed - ModifyOrder() error")
|
||||
}
|
||||
@@ -444,7 +440,7 @@ func TestWithdraw(t *testing.T) {
|
||||
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.BTC,
|
||||
Currency: currency.BTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
@@ -468,7 +464,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.KRW,
|
||||
Currency: currency.KRW,
|
||||
Description: "WITHDRAW IT ALL",
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
@@ -477,7 +473,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "Hyrule",
|
||||
BankName: "Federal Reserve Bank",
|
||||
WireCurrency: symbol.KRW,
|
||||
WireCurrency: currency.KRW.String(),
|
||||
SwiftCode: "Taylor",
|
||||
RequiresIntermediaryBank: false,
|
||||
IsExpressWire: false,
|
||||
@@ -510,12 +506,12 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if testAPIKey != "" && testAPISecret != "" {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package bithumb
|
||||
|
||||
import "github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
import "github.com/thrasher-/gocryptotrader/currency"
|
||||
|
||||
// Ticker holds ticker data
|
||||
type Ticker struct {
|
||||
@@ -225,51 +225,51 @@ type MarketSell struct {
|
||||
|
||||
// WithdrawalFees the large list of predefined withdrawal fees
|
||||
// Prone to change
|
||||
var WithdrawalFees = map[string]float64{
|
||||
symbol.KRW: 1000,
|
||||
symbol.BTC: 0.001,
|
||||
symbol.ETH: 0.01,
|
||||
symbol.DASH: 0.01,
|
||||
symbol.LTC: 0.01,
|
||||
symbol.ETC: 0.01,
|
||||
symbol.XRP: 1,
|
||||
symbol.BCH: 0.001,
|
||||
symbol.XMR: 0.05,
|
||||
symbol.ZEC: 0.001,
|
||||
symbol.QTUM: 0.05,
|
||||
symbol.BTG: 0.001,
|
||||
symbol.ICX: 1,
|
||||
symbol.TRX: 5,
|
||||
symbol.ELF: 5,
|
||||
symbol.MITH: 5,
|
||||
symbol.MCO: 0.5,
|
||||
symbol.OMG: 0.4,
|
||||
symbol.KNC: 3,
|
||||
symbol.GNT: 12,
|
||||
symbol.HSR: 0.2,
|
||||
symbol.ZIL: 30,
|
||||
symbol.ETHOS: 2,
|
||||
symbol.PAY: 2.4,
|
||||
symbol.WAX: 5,
|
||||
symbol.POWR: 5,
|
||||
symbol.LRC: 10,
|
||||
symbol.GTO: 15,
|
||||
symbol.STEEM: 0.01,
|
||||
symbol.STRAT: 0.2,
|
||||
symbol.PPT: 0.5,
|
||||
symbol.CTXC: 4,
|
||||
symbol.CMT: 20,
|
||||
symbol.THETA: 24,
|
||||
symbol.WTC: 0.7,
|
||||
symbol.ITC: 5,
|
||||
symbol.TRUE: 4,
|
||||
symbol.ABT: 5,
|
||||
symbol.RNT: 20,
|
||||
symbol.PLY: 20,
|
||||
symbol.WAVES: 0.01,
|
||||
symbol.LINK: 10,
|
||||
symbol.ENJ: 35,
|
||||
symbol.PST: 30,
|
||||
var WithdrawalFees = map[currency.Code]float64{
|
||||
currency.KRW: 1000,
|
||||
currency.BTC: 0.001,
|
||||
currency.ETH: 0.01,
|
||||
currency.DASH: 0.01,
|
||||
currency.LTC: 0.01,
|
||||
currency.ETC: 0.01,
|
||||
currency.XRP: 1,
|
||||
currency.BCH: 0.001,
|
||||
currency.XMR: 0.05,
|
||||
currency.ZEC: 0.001,
|
||||
currency.QTUM: 0.05,
|
||||
currency.BTG: 0.001,
|
||||
currency.ICX: 1,
|
||||
currency.TRX: 5,
|
||||
currency.ELF: 5,
|
||||
currency.MITH: 5,
|
||||
currency.MCO: 0.5,
|
||||
currency.OMG: 0.4,
|
||||
currency.KNC: 3,
|
||||
currency.GNT: 12,
|
||||
currency.HSR: 0.2,
|
||||
currency.ZIL: 30,
|
||||
currency.ETHOS: 2,
|
||||
currency.PAY: 2.4,
|
||||
currency.WAX: 5,
|
||||
currency.POWR: 5,
|
||||
currency.LRC: 10,
|
||||
currency.GTO: 15,
|
||||
currency.STEEM: 0.01,
|
||||
currency.STRAT: 0.2,
|
||||
currency.PPT: 0.5,
|
||||
currency.CTXC: 4,
|
||||
currency.CMT: 20,
|
||||
currency.THETA: 24,
|
||||
currency.WTC: 0.7,
|
||||
currency.ITC: 5,
|
||||
currency.TRUE: 4,
|
||||
currency.ABT: 5,
|
||||
currency.RNT: 20,
|
||||
currency.PLY: 20,
|
||||
currency.WAVES: 0.01,
|
||||
currency.LINK: 10,
|
||||
currency.ENJ: 35,
|
||||
currency.PST: 30,
|
||||
}
|
||||
|
||||
// FullBalance defines a return type with full balance data
|
||||
|
||||
@@ -9,8 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -38,7 +37,13 @@ func (b *Bithumb) Run() {
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to get available symbols.\n", b.GetName())
|
||||
} else {
|
||||
err = b.UpdateCurrencies(exchangeProducts, false, false)
|
||||
var newExchangeProducts currency.Pairs
|
||||
for _, p := range exchangeProducts {
|
||||
newExchangeProducts = append(newExchangeProducts,
|
||||
currency.NewPairFromString(p))
|
||||
}
|
||||
|
||||
err = b.UpdateCurrencies(newExchangeProducts, false, false)
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to update available symbols.\n", b.GetName())
|
||||
}
|
||||
@@ -60,7 +65,7 @@ func (b *Bithumb) GetTradingPairs() ([]string, error) {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *Bithumb) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bithumb) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
|
||||
tickers, err := b.GetAllTickers()
|
||||
@@ -69,7 +74,7 @@ func (b *Bithumb) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Pr
|
||||
}
|
||||
|
||||
for _, x := range b.GetEnabledCurrencies() {
|
||||
currency := x.FirstCurrency.String()
|
||||
currency := x.Base.String()
|
||||
var tp ticker.Price
|
||||
tp.Pair = x
|
||||
tp.Ask = tickers[currency].SellPrice
|
||||
@@ -78,13 +83,17 @@ func (b *Bithumb) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Pr
|
||||
tp.Last = tickers[currency].ClosingPrice
|
||||
tp.Volume = tickers[currency].Volume1Day
|
||||
tp.High = tickers[currency].MaxPrice
|
||||
ticker.ProcessTicker(b.Name, x, tp, assetType)
|
||||
|
||||
err = ticker.ProcessTicker(b.Name, tp, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
}
|
||||
return ticker.GetTicker(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (b *Bithumb) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bithumb) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tickerNew, err := ticker.GetTicker(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateTicker(p, assetType)
|
||||
@@ -93,8 +102,8 @@ func (b *Bithumb) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns orderbook base on the currency pair
|
||||
func (b *Bithumb) GetOrderbookEx(currency pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(b.GetName(), currency, assetType)
|
||||
func (b *Bithumb) GetOrderbookEx(currency currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(b.GetName(), currency, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateOrderbook(currency, assetType)
|
||||
}
|
||||
@@ -102,9 +111,9 @@ func (b *Bithumb) GetOrderbookEx(currency pair.CurrencyPair, assetType string) (
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *Bithumb) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (b *Bithumb) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
currency := p.FirstCurrency.String()
|
||||
currency := p.Base.String()
|
||||
|
||||
orderbookNew, err := b.GetOrderBook(currency)
|
||||
if err != nil {
|
||||
@@ -119,8 +128,16 @@ func (b *Bithumb) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderb
|
||||
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: asks.Quantity, Price: asks.Price})
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(b.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = b.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetAccountInfo retrieves balances for all enabled currencies for the
|
||||
@@ -141,7 +158,7 @@ func (b *Bithumb) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
}
|
||||
|
||||
exchangeBalances = append(exchangeBalances, exchange.AccountCurrencyInfo{
|
||||
CurrencyName: key,
|
||||
CurrencyName: currency.NewCode(key),
|
||||
TotalValue: totalAmount,
|
||||
Hold: hold,
|
||||
})
|
||||
@@ -163,7 +180,7 @@ func (b *Bithumb) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *Bithumb) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *Bithumb) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
@@ -171,17 +188,17 @@ func (b *Bithumb) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]e
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
// TODO: Fill this out to support limit orders
|
||||
func (b *Bithumb) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, _ exchange.OrderType, amount, _ float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
func (b *Bithumb) SubmitOrder(p currency.Pair, side exchange.OrderSide, _ exchange.OrderType, amount, _ float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
var err error
|
||||
var orderID string
|
||||
if side == exchange.BuyOrderSide {
|
||||
var result MarketBuy
|
||||
result, err = b.MarketBuyOrder(p.FirstCurrency.String(), amount)
|
||||
result, err = b.MarketBuyOrder(p.Base.String(), amount)
|
||||
orderID = result.OrderID
|
||||
} else if side == exchange.SellOrderSide {
|
||||
var result MarketSell
|
||||
result, err = b.MarketSellOrder(p.FirstCurrency.String(), amount)
|
||||
result, err = b.MarketSellOrder(p.Base.String(), amount)
|
||||
orderID = result.OrderID
|
||||
}
|
||||
|
||||
@@ -200,7 +217,7 @@ func (b *Bithumb) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, _ ex
|
||||
// market conversion
|
||||
func (b *Bithumb) ModifyOrder(action exchange.ModifyOrder) (string, error) {
|
||||
order, err := b.ModifyTrade(action.OrderID,
|
||||
action.Currency.FirstCurrency.String(),
|
||||
action.CurrencyPair.Base.String(),
|
||||
common.StringToLower(action.OrderSide.ToString()),
|
||||
action.Amount,
|
||||
int64(action.Price))
|
||||
@@ -214,7 +231,9 @@ func (b *Bithumb) ModifyOrder(action exchange.ModifyOrder) (string, error) {
|
||||
|
||||
// CancelOrder cancels an order by its corresponding ID number
|
||||
func (b *Bithumb) CancelOrder(order exchange.OrderCancellation) error {
|
||||
_, err := b.CancelTrade(order.Side.ToString(), order.OrderID, order.CurrencyPair.FirstCurrency.String())
|
||||
_, err := b.CancelTrade(order.Side.ToString(),
|
||||
order.OrderID,
|
||||
order.CurrencyPair.Base.String())
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -226,7 +245,11 @@ func (b *Bithumb) CancelAllOrders(orderCancellation exchange.OrderCancellation)
|
||||
var allOrders []OrderData
|
||||
|
||||
for _, currency := range b.GetEnabledCurrencies() {
|
||||
orders, err := b.GetOrders("", orderCancellation.Side.ToString(), "100", "", currency.FirstCurrency.String())
|
||||
orders, err := b.GetOrders("",
|
||||
orderCancellation.Side.ToString(),
|
||||
"100",
|
||||
"",
|
||||
currency.Base.String())
|
||||
if err != nil {
|
||||
return cancelAllOrdersResponse, err
|
||||
}
|
||||
@@ -234,7 +257,9 @@ func (b *Bithumb) CancelAllOrders(orderCancellation exchange.OrderCancellation)
|
||||
}
|
||||
|
||||
for _, order := range allOrders {
|
||||
_, err := b.CancelTrade(orderCancellation.Side.ToString(), order.OrderID, orderCancellation.CurrencyPair.FirstCurrency.String())
|
||||
_, err := b.CancelTrade(orderCancellation.Side.ToString(),
|
||||
order.OrderID,
|
||||
orderCancellation.CurrencyPair.Base.String())
|
||||
if err != nil {
|
||||
cancelAllOrdersResponse.OrderStatus[order.OrderID] = err.Error()
|
||||
}
|
||||
@@ -250,7 +275,7 @@ func (b *Bithumb) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *Bithumb) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) (string, error) {
|
||||
func (b *Bithumb) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) {
|
||||
addr, err := b.GetWalletAddress(cryptocurrency.String())
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -272,7 +297,7 @@ func (b *Bithumb) WithdrawFiatFunds(withdrawRequest exchange.WithdrawRequest) (s
|
||||
if math.Mod(withdrawRequest.Amount, 1) != 0 {
|
||||
return "", errors.New("currency KRW does not support decimal places")
|
||||
}
|
||||
if withdrawRequest.Currency.String() != symbol.KRW {
|
||||
if withdrawRequest.Currency != currency.KRW {
|
||||
return "", errors.New("only KRW is supported")
|
||||
}
|
||||
bankDetails := fmt.Sprintf("%v_%v", withdrawRequest.BankCode, withdrawRequest.BankName)
|
||||
@@ -326,7 +351,9 @@ func (b *Bithumb) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
Price: order.Price,
|
||||
RemainingAmount: order.UnitsRemaining,
|
||||
Status: string(exchange.ActiveOrderStatus),
|
||||
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.OrderCurrency, order.PaymentCurrency, b.ConfigCurrencyPairFormat.Delimiter),
|
||||
CurrencyPair: currency.NewPairWithDelimiter(order.OrderCurrency,
|
||||
order.PaymentCurrency,
|
||||
b.ConfigCurrencyPairFormat.Delimiter),
|
||||
}
|
||||
|
||||
if order.Type == "bid" {
|
||||
@@ -339,7 +366,8 @@ func (b *Bithumb) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
}
|
||||
|
||||
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
|
||||
|
||||
return orders, nil
|
||||
@@ -367,7 +395,9 @@ func (b *Bithumb) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
OrderDate: orderDate,
|
||||
Price: order.Price,
|
||||
RemainingAmount: order.UnitsRemaining,
|
||||
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.OrderCurrency, order.PaymentCurrency, b.ConfigCurrencyPairFormat.Delimiter),
|
||||
CurrencyPair: currency.NewPairWithDelimiter(order.OrderCurrency,
|
||||
order.PaymentCurrency,
|
||||
b.ConfigCurrencyPairFormat.Delimiter),
|
||||
}
|
||||
|
||||
if order.Type == "bid" {
|
||||
@@ -380,7 +410,8 @@ func (b *Bithumb) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
}
|
||||
|
||||
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
|
||||
|
||||
return orders, nil
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -149,9 +149,9 @@ func (b *Bitmex) Setup(exch config.ExchangeConfig) {
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.Websocket.SetWsStatusAndConnection(exch.Websocket)
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
err := b.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -705,13 +705,13 @@ func (b *Bitmex) ConfirmWithdrawal(token string) (TransactionInfo, error) {
|
||||
}
|
||||
|
||||
// GetCryptoDepositAddress returns a deposit address for a cryptocurency
|
||||
func (b *Bitmex) GetCryptoDepositAddress(currency string) (string, error) {
|
||||
func (b *Bitmex) GetCryptoDepositAddress(cryptoCurrency string) (string, error) {
|
||||
var address string
|
||||
|
||||
if !strings.EqualFold(currency, symbol.XBT) {
|
||||
if !strings.EqualFold(cryptoCurrency, currency.XBT.String()) {
|
||||
return "",
|
||||
fmt.Errorf("cryptocurrency %s deposits are not supported by exchange only bitcoin",
|
||||
currency)
|
||||
cryptoCurrency)
|
||||
}
|
||||
|
||||
return address, b.SendAuthenticatedHTTPRequest(http.MethodGet,
|
||||
|
||||
@@ -7,8 +7,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -363,13 +362,10 @@ func TestGetPreviousTrades(t *testing.T) {
|
||||
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,7 +425,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -438,7 +434,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -478,8 +474,9 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
TestSetup(t)
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.LTC, symbol.BTC)},
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []currency.Pair{currency.NewPair(currency.LTC,
|
||||
currency.BTC)},
|
||||
}
|
||||
|
||||
_, err := b.GetOrderHistory(getOrdersRequest)
|
||||
@@ -508,10 +505,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "",
|
||||
FirstCurrency: symbol.XBT,
|
||||
SecondCurrency: symbol.USD,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "",
|
||||
Base: currency.XBT,
|
||||
Quote: currency.USD,
|
||||
}
|
||||
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -529,7 +526,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "123456789012345678901234567890123456",
|
||||
@@ -555,7 +552,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "123456789012345678901234567890123456",
|
||||
@@ -604,7 +601,7 @@ func TestWithdraw(t *testing.T) {
|
||||
TestSetup(t)
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: "XBt",
|
||||
Currency: currency.XBT,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
OneTimePassword: 000000,
|
||||
@@ -657,12 +654,12 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if areTestAPIKeysSet() {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
@@ -236,7 +236,7 @@ func (b *Bitmex) wsHandleIncomingData() {
|
||||
continue
|
||||
}
|
||||
|
||||
p := pair.NewCurrencyPairFromString(orderbooks.Data[0].Symbol)
|
||||
p := currency.NewPairFromString(orderbooks.Data[0].Symbol)
|
||||
// TODO: update this to support multiple asset types
|
||||
err = b.processOrderbook(orderbooks.Data, orderbooks.Action, p, "CONTRACT")
|
||||
if err != nil {
|
||||
@@ -269,7 +269,7 @@ func (b *Bitmex) wsHandleIncomingData() {
|
||||
Timestamp: timestamp,
|
||||
Price: trade.Price,
|
||||
Amount: float64(trade.Size),
|
||||
CurrencyPair: pair.NewCurrencyPairFromString(trade.Symbol),
|
||||
CurrencyPair: currency.NewPairFromString(trade.Symbol),
|
||||
Exchange: b.GetName(),
|
||||
AssetType: "CONTRACT",
|
||||
Side: trade.Side,
|
||||
@@ -300,10 +300,10 @@ func (b *Bitmex) wsHandleIncomingData() {
|
||||
}
|
||||
}
|
||||
|
||||
var snapshotloaded = make(map[pair.CurrencyPair]map[string]bool)
|
||||
var snapshotloaded = make(map[currency.Pair]map[string]bool)
|
||||
|
||||
// ProcessOrderbook processes orderbook updates
|
||||
func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, currencyPair pair.CurrencyPair, assetType string) error { // nolint: unparam
|
||||
func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, currencyPair currency.Pair, assetType string) error { // nolint: unparam
|
||||
if len(data) < 1 {
|
||||
return errors.New("bitmex_websocket.go error - no orderbook data")
|
||||
}
|
||||
@@ -345,8 +345,6 @@ func (b *Bitmex) processOrderbook(data []OrderBookL2, action string, currencyPai
|
||||
newOrderbook.Asks = asks
|
||||
newOrderbook.Bids = bids
|
||||
newOrderbook.AssetType = assetType
|
||||
newOrderbook.CurrencyPair = currencyPair.Pair().String()
|
||||
newOrderbook.LastUpdated = time.Now()
|
||||
newOrderbook.Pair = currencyPair
|
||||
|
||||
err := b.Websocket.Orderbook.LoadSnapshot(newOrderbook, b.GetName(), false)
|
||||
@@ -415,8 +413,8 @@ func (b *Bitmex) websocketSubscribe() error {
|
||||
// Orderbook and Trade subscribe
|
||||
// NOTE more added here in future
|
||||
subscriber.Arguments = append(subscriber.Arguments,
|
||||
bitmexWSOrderbookL2+":"+contract.Pair().String(),
|
||||
bitmexWSTrade+":"+contract.Pair().String())
|
||||
bitmexWSOrderbookL2+":"+contract.String(),
|
||||
bitmexWSTrade+":"+contract.String())
|
||||
}
|
||||
|
||||
return b.WebsocketConn.WriteJSON(subscriber)
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -42,7 +42,13 @@ func (b *Bitmex) Run() {
|
||||
exchangeProducts = append(exchangeProducts, info.Symbol)
|
||||
}
|
||||
|
||||
err = b.UpdateCurrencies(exchangeProducts, false, false)
|
||||
var NewExchangeProducts currency.Pairs
|
||||
for _, p := range exchangeProducts {
|
||||
NewExchangeProducts = append(NewExchangeProducts,
|
||||
currency.NewPairFromString(p))
|
||||
}
|
||||
|
||||
err = b.UpdateCurrencies(NewExchangeProducts, false, false)
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to update available currencies.\n", b.GetName())
|
||||
}
|
||||
@@ -50,7 +56,7 @@ func (b *Bitmex) Run() {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *Bitmex) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bitmex) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
currency := exchange.FormatExchangeCurrency(b.Name, p)
|
||||
|
||||
@@ -68,18 +74,13 @@ func (b *Bitmex) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Pri
|
||||
}
|
||||
|
||||
tickerPrice.Pair = p
|
||||
tickerPrice.LastUpdated = time.Now()
|
||||
tickerPrice.CurrencyPair = tick[0].Symbol
|
||||
tickerPrice.Last = tick[0].Price
|
||||
tickerPrice.Volume = float64(tick[0].Size)
|
||||
|
||||
ticker.ProcessTicker(b.Name, p, tickerPrice, assetType)
|
||||
|
||||
return tickerPrice, nil
|
||||
return tickerPrice, ticker.ProcessTicker(b.Name, tickerPrice, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (b *Bitmex) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bitmex) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tickerNew, err := ticker.GetTicker(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateTicker(p, assetType)
|
||||
@@ -88,8 +89,8 @@ func (b *Bitmex) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.P
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns orderbook base on the currency pair
|
||||
func (b *Bitmex) GetOrderbookEx(currency pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(b.GetName(), currency, assetType)
|
||||
func (b *Bitmex) GetOrderbookEx(currency currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(b.GetName(), currency, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateOrderbook(currency, assetType)
|
||||
}
|
||||
@@ -97,7 +98,7 @@ func (b *Bitmex) GetOrderbookEx(currency pair.CurrencyPair, assetType string) (o
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *Bitmex) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (b *Bitmex) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
|
||||
orderbookNew, err := b.GetOrderbook(OrderBookGetL2Params{
|
||||
@@ -119,9 +120,17 @@ func (b *Bitmex) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbo
|
||||
continue
|
||||
}
|
||||
}
|
||||
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
|
||||
|
||||
return orderbook.GetOrderbook(b.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = b.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetAccountInfo retrieves balances for all enabled currencies for the
|
||||
@@ -138,7 +147,7 @@ func (b *Bitmex) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
var balances []exchange.AccountCurrencyInfo
|
||||
for _, data := range bal {
|
||||
balances = append(balances, exchange.AccountCurrencyInfo{
|
||||
CurrencyName: data.Currency,
|
||||
CurrencyName: currency.NewCode(data.Currency),
|
||||
TotalValue: float64(data.WalletBalance),
|
||||
})
|
||||
}
|
||||
@@ -158,14 +167,14 @@ func (b *Bitmex) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *Bitmex) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *Bitmex) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (b *Bitmex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
func (b *Bitmex) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
|
||||
if math.Mod(amount, 1) != 0 {
|
||||
@@ -175,7 +184,7 @@ func (b *Bitmex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, order
|
||||
|
||||
var orderNewParams = OrderNewParams{
|
||||
OrdType: side.ToString(),
|
||||
Symbol: p.Pair().String(),
|
||||
Symbol: p.String(),
|
||||
OrderQty: amount,
|
||||
Side: side.ToString(),
|
||||
}
|
||||
@@ -252,7 +261,7 @@ func (b *Bitmex) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *Bitmex) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) (string, error) {
|
||||
func (b *Bitmex) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) {
|
||||
return b.GetCryptoDepositAddress(cryptocurrency.String())
|
||||
}
|
||||
|
||||
@@ -319,14 +328,16 @@ func (b *Bitmex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]
|
||||
}
|
||||
|
||||
orderDetail := exchange.OrderDetail{
|
||||
Price: order.Price,
|
||||
Amount: float64(order.OrderQty),
|
||||
Exchange: b.Name,
|
||||
ID: order.OrderID,
|
||||
OrderSide: orderSide,
|
||||
OrderType: orderType,
|
||||
Status: order.OrdStatus,
|
||||
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.Symbol, order.SettlCurrency, b.ConfigCurrencyPairFormat.Delimiter),
|
||||
Price: order.Price,
|
||||
Amount: float64(order.OrderQty),
|
||||
Exchange: b.Name,
|
||||
ID: order.OrderID,
|
||||
OrderSide: orderSide,
|
||||
OrderType: orderType,
|
||||
Status: order.OrdStatus,
|
||||
CurrencyPair: currency.NewPairWithDelimiter(order.Symbol,
|
||||
order.SettlCurrency,
|
||||
b.ConfigCurrencyPairFormat.Delimiter),
|
||||
}
|
||||
|
||||
orders = append(orders, orderDetail)
|
||||
@@ -334,7 +345,8 @@ func (b *Bitmex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]
|
||||
|
||||
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
|
||||
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
|
||||
|
||||
return orders, nil
|
||||
@@ -359,14 +371,16 @@ func (b *Bitmex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]
|
||||
}
|
||||
|
||||
orderDetail := exchange.OrderDetail{
|
||||
Price: order.Price,
|
||||
Amount: float64(order.OrderQty),
|
||||
Exchange: b.Name,
|
||||
ID: order.OrderID,
|
||||
OrderSide: orderSide,
|
||||
OrderType: orderType,
|
||||
Status: order.OrdStatus,
|
||||
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.Symbol, order.SettlCurrency, b.ConfigCurrencyPairFormat.Delimiter),
|
||||
Price: order.Price,
|
||||
Amount: float64(order.OrderQty),
|
||||
Exchange: b.Name,
|
||||
ID: order.OrderID,
|
||||
OrderSide: orderSide,
|
||||
OrderType: orderType,
|
||||
Status: order.OrdStatus,
|
||||
CurrencyPair: currency.NewPairWithDelimiter(order.Symbol,
|
||||
order.SettlCurrency,
|
||||
b.ConfigCurrencyPairFormat.Delimiter),
|
||||
}
|
||||
|
||||
orders = append(orders, orderDetail)
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -104,9 +104,9 @@ func (b *Bitstamp) Setup(exch config.ExchangeConfig) {
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.Websocket.SetWsStatusAndConnection(exch.Websocket)
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
b.APIKey = exch.APIKey
|
||||
b.APISecret = exch.APISecret
|
||||
b.SetAPIKeys(exch.APIKey, exch.APISecret, b.ClientID, false)
|
||||
@@ -154,7 +154,10 @@ func (b *Bitstamp) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
fee = b.CalculateTradingFee(feeBuilder.FirstCurrency+feeBuilder.SecondCurrency, feeBuilder.PurchasePrice, feeBuilder.Amount)
|
||||
fee = b.CalculateTradingFee(feeBuilder.Pair.Base,
|
||||
feeBuilder.Pair.Quote,
|
||||
feeBuilder.PurchasePrice,
|
||||
feeBuilder.Amount)
|
||||
case exchange.CyptocurrencyDepositFee:
|
||||
fee = 0
|
||||
case exchange.InternationalBankDepositFee:
|
||||
@@ -192,19 +195,19 @@ func getInternationalBankDepositFee(amount float64) float64 {
|
||||
}
|
||||
|
||||
// CalculateTradingFee returns fee on a currency pair
|
||||
func (b *Bitstamp) CalculateTradingFee(currency string, purchasePrice, amount float64) float64 {
|
||||
func (b *Bitstamp) CalculateTradingFee(base, quote currency.Code, purchasePrice, amount float64) float64 {
|
||||
var fee float64
|
||||
|
||||
switch currency {
|
||||
case symbol.BTC + symbol.USD:
|
||||
switch base.String() + quote.String() {
|
||||
case currency.BTC.String() + currency.USD.String():
|
||||
fee = b.Balance.BTCUSDFee
|
||||
case symbol.BTC + symbol.EUR:
|
||||
case currency.BTC.String() + currency.EUR.String():
|
||||
fee = b.Balance.BTCEURFee
|
||||
case symbol.XRP + symbol.EUR:
|
||||
case currency.XRP.String() + currency.EUR.String():
|
||||
fee = b.Balance.XRPEURFee
|
||||
case symbol.XRP + symbol.USD:
|
||||
case currency.XRP.String() + currency.USD.String():
|
||||
fee = b.Balance.XRPUSDFee
|
||||
case symbol.EUR + symbol.USD:
|
||||
case currency.EUR.String() + currency.USD.String():
|
||||
fee = b.Balance.EURUSDFee
|
||||
default:
|
||||
fee = 0
|
||||
@@ -572,27 +575,27 @@ func (b *Bitstamp) OpenInternationalBankWithdrawal(amount float64, currency,
|
||||
|
||||
// GetCryptoDepositAddress returns a depositing address by crypto
|
||||
// crypto - example "btc", "ltc", "eth", "xrp" or "bch"
|
||||
func (b *Bitstamp) GetCryptoDepositAddress(crypto string) (string, error) {
|
||||
func (b *Bitstamp) GetCryptoDepositAddress(crypto currency.Code) (string, error) {
|
||||
var resp string
|
||||
|
||||
switch crypto {
|
||||
case symbol.BTC:
|
||||
case currency.BTC:
|
||||
return resp,
|
||||
b.SendAuthenticatedHTTPRequest(bitstampAPIBitcoinDeposit, false, nil, &resp)
|
||||
|
||||
case symbol.LTC:
|
||||
case currency.LTC:
|
||||
return resp,
|
||||
b.SendAuthenticatedHTTPRequest(bitstampAPILitecoinDeposit, true, nil, &resp)
|
||||
|
||||
case symbol.ETH:
|
||||
case currency.ETH:
|
||||
return resp,
|
||||
b.SendAuthenticatedHTTPRequest(bitstampAPIEthereumDeposit, true, nil, &resp)
|
||||
|
||||
case symbol.XRP:
|
||||
case currency.XRP:
|
||||
return resp,
|
||||
b.SendAuthenticatedHTTPRequest(bitstampAPIXrpDeposit, true, nil, &resp)
|
||||
|
||||
case symbol.BCH:
|
||||
case currency.BCH:
|
||||
return resp,
|
||||
b.SendAuthenticatedHTTPRequest(bitstampAPIBitcoinCashDeposit, true, nil, &resp)
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -64,13 +63,10 @@ func TestSetup(t *testing.T) {
|
||||
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +126,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(7.5) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(7.5), resp)
|
||||
t.Error(err)
|
||||
@@ -139,7 +135,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(15) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(15), resp)
|
||||
t.Error(err)
|
||||
@@ -153,27 +149,29 @@ func TestCalculateTradingFee(t *testing.T) {
|
||||
b.Balance.BTCUSDFee = 1
|
||||
b.Balance.BTCEURFee = 0
|
||||
|
||||
if resp := b.CalculateTradingFee(symbol.BTC+symbol.USD, 0, 0); resp != 0 {
|
||||
if resp := b.CalculateTradingFee(currency.BTC, currency.USD, 0, 0); resp != 0 {
|
||||
t.Error("Test Failed - GetFee() error")
|
||||
}
|
||||
if resp := b.CalculateTradingFee(symbol.BTC+symbol.USD, 2, 2); resp != float64(4) {
|
||||
if resp := b.CalculateTradingFee(currency.BTC, currency.USD, 2, 2); resp != float64(4) {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(4), resp)
|
||||
}
|
||||
if resp := b.CalculateTradingFee(symbol.BTC+symbol.EUR, 2, 2); resp != float64(0) {
|
||||
if resp := b.CalculateTradingFee(currency.BTC, currency.EUR, 2, 2); resp != float64(0) {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
}
|
||||
if resp := b.CalculateTradingFee("bla", 0, 0); resp != 0 {
|
||||
|
||||
dummy1, dummy2 := currency.NewCode(""), currency.NewCode("")
|
||||
if resp := b.CalculateTradingFee(dummy1, dummy2, 0, 0); resp != 0 {
|
||||
t.Error("Test Failed - GetFee() error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetTicker(symbol.BTC+symbol.USD, false)
|
||||
_, err := b.GetTicker(currency.BTC.String()+currency.USD.String(), false)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetTicker() error", err)
|
||||
}
|
||||
_, err = b.GetTicker(symbol.BTC+symbol.USD, true)
|
||||
_, err = b.GetTicker(currency.BTC.String()+currency.USD.String(), true)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetTicker() error", err)
|
||||
}
|
||||
@@ -181,7 +179,7 @@ func TestGetTicker(t *testing.T) {
|
||||
|
||||
func TestGetOrderbook(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetOrderbook(symbol.BTC + symbol.USD)
|
||||
_, err := b.GetOrderbook(currency.BTC.String() + currency.USD.String())
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetOrderbook() error", err)
|
||||
}
|
||||
@@ -200,7 +198,7 @@ func TestGetTransactions(t *testing.T) {
|
||||
value := url.Values{}
|
||||
value.Set("time", "hour")
|
||||
|
||||
_, err := b.GetTransactions(symbol.BTC+symbol.USD, value)
|
||||
_, err := b.GetTransactions(currency.BTC.String()+currency.USD.String(), value)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetTransactions() error", err)
|
||||
}
|
||||
@@ -325,7 +323,7 @@ func TestCryptoWithdrawal(t *testing.T) {
|
||||
func TestGetBitcoinDepositAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetCryptoDepositAddress("btc")
|
||||
_, err := b.GetCryptoDepositAddress(currency.BTC)
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetCryptoDepositAddress() error", err)
|
||||
}
|
||||
@@ -418,10 +416,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "",
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.USD,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.USD,
|
||||
}
|
||||
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -439,7 +437,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -465,7 +463,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -500,7 +498,7 @@ func TestWithdraw(t *testing.T) {
|
||||
TestSetup(t)
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.BTC,
|
||||
Currency: currency.BTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
@@ -528,7 +526,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.USD,
|
||||
Currency: currency.USD,
|
||||
Description: "WITHDRAW IT ALL",
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
@@ -536,7 +534,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "AU",
|
||||
BankName: "Federal Reserve Bank",
|
||||
WireCurrency: symbol.USD,
|
||||
WireCurrency: currency.USD.String(),
|
||||
SwiftCode: "CTBAAU2S",
|
||||
RequiresIntermediaryBank: false,
|
||||
IsExpressWire: false,
|
||||
@@ -563,7 +561,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.USD,
|
||||
Currency: currency.USD,
|
||||
Description: "WITHDRAW IT ALL",
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
@@ -571,7 +569,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "AU",
|
||||
BankName: "Federal Reserve Bank",
|
||||
WireCurrency: symbol.USD,
|
||||
WireCurrency: currency.USD.String(),
|
||||
SwiftCode: "CTBAAU2S",
|
||||
RequiresIntermediaryBank: false,
|
||||
IsExpressWire: false,
|
||||
@@ -596,12 +594,12 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if areTestAPIKeysSet() && customerID != "" {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress error cannot be nil")
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
@@ -60,7 +60,7 @@ func (b *Bitstamp) findPairFromChannel(channelName string) (string, error) {
|
||||
tradingPair := strings.ToUpper(split[len(split)-1])
|
||||
|
||||
for _, enabledPair := range b.EnabledPairs {
|
||||
if enabledPair == tradingPair {
|
||||
if enabledPair.String() == tradingPair {
|
||||
return tradingPair, nil
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ func (b *Bitstamp) WsConnect() error {
|
||||
go b.WsReadData()
|
||||
|
||||
for _, p := range b.GetEnabledCurrencies() {
|
||||
orderbookSeed, err := b.GetOrderbook(p.Pair().String())
|
||||
orderbookSeed, err := b.GetOrderbook(p.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -127,9 +127,7 @@ func (b *Bitstamp) WsConnect() error {
|
||||
|
||||
newOrderbook.Asks = asks
|
||||
newOrderbook.Bids = bids
|
||||
newOrderbook.CurrencyPair = p.Pair().String()
|
||||
newOrderbook.Pair = p
|
||||
newOrderbook.LastUpdated = time.Unix(0, orderbookSeed.Timestamp)
|
||||
newOrderbook.AssetType = "SPOT"
|
||||
|
||||
err = b.Websocket.Orderbook.LoadSnapshot(newOrderbook, b.GetName(), false)
|
||||
@@ -144,7 +142,7 @@ func (b *Bitstamp) WsConnect() error {
|
||||
}
|
||||
|
||||
err = b.WebsocketConn.Client.Subscribe(fmt.Sprintf("live_trades_%s",
|
||||
strings.ToLower(p.Pair().String())))
|
||||
p.Lower().String()))
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s Websocket Trade subscription error: %s",
|
||||
@@ -153,7 +151,7 @@ func (b *Bitstamp) WsConnect() error {
|
||||
}
|
||||
|
||||
err = b.WebsocketConn.Client.Subscribe(fmt.Sprintf("diff_order_book_%s",
|
||||
strings.ToLower(p.Pair().String())))
|
||||
p.Lower().String()))
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s Websocket Trade subscription error: %s",
|
||||
@@ -194,7 +192,7 @@ func (b *Bitstamp) WsReadData() {
|
||||
}
|
||||
|
||||
currencyPair := common.SplitStrings(data.Channel, "_")
|
||||
p := pair.NewCurrencyPairFromString(common.StringToUpper(currencyPair[3]))
|
||||
p := currency.NewPairFromString(common.StringToUpper(currencyPair[3]))
|
||||
|
||||
err = b.WsUpdateOrderbook(result, p, "SPOT")
|
||||
if err != nil {
|
||||
@@ -217,7 +215,7 @@ func (b *Bitstamp) WsReadData() {
|
||||
b.Websocket.DataHandler <- exchange.TradeData{
|
||||
Price: result.Price,
|
||||
Amount: result.Amount,
|
||||
CurrencyPair: pair.NewCurrencyPairFromString(currencyPair[2]),
|
||||
CurrencyPair: currency.NewPairFromString(currencyPair[2]),
|
||||
Exchange: b.GetName(),
|
||||
AssetType: "SPOT",
|
||||
}
|
||||
@@ -226,7 +224,7 @@ func (b *Bitstamp) WsReadData() {
|
||||
}
|
||||
|
||||
// WsUpdateOrderbook updates local cache of orderbook information
|
||||
func (b *Bitstamp) WsUpdateOrderbook(ob PusherOrderbook, p pair.CurrencyPair, assetType string) error {
|
||||
func (b *Bitstamp) WsUpdateOrderbook(ob PusherOrderbook, p currency.Pair, assetType string) error {
|
||||
if len(ob.Asks) == 0 && len(ob.Bids) == 0 {
|
||||
return errors.New("bitstamp_websocket.go error - no orderbook data")
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -46,7 +45,14 @@ func (b *Bitstamp) Run() {
|
||||
p := strings.Split(pairs[x].Name, "/")
|
||||
currencies = append(currencies, p[0]+p[1])
|
||||
}
|
||||
err = b.UpdateCurrencies(currencies, false, false)
|
||||
|
||||
var newCurrencies currency.Pairs
|
||||
for _, p := range currencies {
|
||||
newCurrencies = append(newCurrencies,
|
||||
currency.NewPairFromString(p))
|
||||
}
|
||||
|
||||
err = b.UpdateCurrencies(newCurrencies, false, false)
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to update available currencies.\n", b.Name)
|
||||
}
|
||||
@@ -54,9 +60,9 @@ func (b *Bitstamp) Run() {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *Bitstamp) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bitstamp) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
tick, err := b.GetTicker(p.Pair().String(), false)
|
||||
tick, err := b.GetTicker(p.String(), false)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
|
||||
@@ -68,12 +74,17 @@ func (b *Bitstamp) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.P
|
||||
tickerPrice.Last = tick.Last
|
||||
tickerPrice.Volume = tick.Volume
|
||||
tickerPrice.High = tick.High
|
||||
ticker.ProcessTicker(b.GetName(), p, tickerPrice, assetType)
|
||||
|
||||
err = ticker.ProcessTicker(b.GetName(), tickerPrice, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
|
||||
return ticker.GetTicker(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (b *Bitstamp) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bitstamp) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tick, err := ticker.GetTicker(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateTicker(p, assetType)
|
||||
@@ -88,8 +99,8 @@ func (b *Bitstamp) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error)
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns the orderbook for a currency pair
|
||||
func (b *Bitstamp) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
|
||||
func (b *Bitstamp) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateOrderbook(p, assetType)
|
||||
}
|
||||
@@ -97,9 +108,9 @@ func (b *Bitstamp) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderb
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *Bitstamp) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (b *Bitstamp) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
orderbookNew, err := b.GetOrderbook(p.Pair().String())
|
||||
orderbookNew, err := b.GetOrderbook(p.String())
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
@@ -114,8 +125,16 @@ func (b *Bitstamp) UpdateOrderbook(p pair.CurrencyPair, assetType string) (order
|
||||
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data.Amount, Price: data.Price})
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(b.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = b.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetAccountInfo retrieves balances for all enabled currencies for the
|
||||
@@ -130,22 +149,22 @@ func (b *Bitstamp) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
|
||||
var currencies = []exchange.AccountCurrencyInfo{
|
||||
{
|
||||
CurrencyName: "BTC",
|
||||
CurrencyName: currency.BTC,
|
||||
TotalValue: accountBalance.BTCAvailable,
|
||||
Hold: accountBalance.BTCReserved,
|
||||
},
|
||||
{
|
||||
CurrencyName: "XRP",
|
||||
CurrencyName: currency.XRP,
|
||||
TotalValue: accountBalance.XRPAvailable,
|
||||
Hold: accountBalance.XRPReserved,
|
||||
},
|
||||
{
|
||||
CurrencyName: "USD",
|
||||
CurrencyName: currency.USD,
|
||||
TotalValue: accountBalance.USDAvailable,
|
||||
Hold: accountBalance.USDReserved,
|
||||
},
|
||||
{
|
||||
CurrencyName: "EUR",
|
||||
CurrencyName: currency.EUR,
|
||||
TotalValue: accountBalance.EURAvailable,
|
||||
Hold: accountBalance.EURReserved,
|
||||
},
|
||||
@@ -165,18 +184,18 @@ func (b *Bitstamp) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *Bitstamp) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *Bitstamp) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (b *Bitstamp) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
func (b *Bitstamp) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
buy := side == exchange.BuyOrderSide
|
||||
market := orderType == exchange.MarketOrderType
|
||||
response, err := b.PlaceOrder(p.Pair().String(), price, amount, buy, market)
|
||||
response, err := b.PlaceOrder(p.String(), price, amount, buy, market)
|
||||
|
||||
if response.ID > 0 {
|
||||
submitOrderResponse.OrderID = fmt.Sprintf("%v", response.ID)
|
||||
@@ -224,8 +243,8 @@ func (b *Bitstamp) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *Bitstamp) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) (string, error) {
|
||||
return b.GetCryptoDepositAddress(cryptocurrency.String())
|
||||
func (b *Bitstamp) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) {
|
||||
return b.GetCryptoDepositAddress(cryptocurrency)
|
||||
}
|
||||
|
||||
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is
|
||||
@@ -290,7 +309,7 @@ func (b *Bitstamp) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) (
|
||||
if len(getOrdersRequest.Currencies) != 1 {
|
||||
currPair = "all"
|
||||
} else {
|
||||
currPair = getOrdersRequest.Currencies[0].Pair().String()
|
||||
currPair = getOrdersRequest.Currencies[0].String()
|
||||
}
|
||||
|
||||
resp, err := b.GetOpenOrders(currPair)
|
||||
@@ -299,17 +318,15 @@ func (b *Bitstamp) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) (
|
||||
}
|
||||
|
||||
for _, order := range resp {
|
||||
symbolOne := order.Currency[0:3]
|
||||
symbolTwo := order.Currency[len(order.Currency)-3:]
|
||||
orderDate := time.Unix(order.Date, 0)
|
||||
|
||||
orders = append(orders, exchange.OrderDetail{
|
||||
Amount: order.Amount,
|
||||
ID: fmt.Sprintf("%v", order.ID),
|
||||
Price: order.Price,
|
||||
OrderDate: orderDate,
|
||||
CurrencyPair: pair.NewCurrencyPair(symbolOne, symbolTwo),
|
||||
Exchange: b.Name,
|
||||
Amount: order.Amount,
|
||||
ID: fmt.Sprintf("%v", order.ID),
|
||||
Price: order.Price,
|
||||
OrderDate: orderDate,
|
||||
CurrencyPair: currency.NewPairFromStrings(order.Currency[0:3],
|
||||
order.Currency[len(order.Currency)-3:]),
|
||||
Exchange: b.Name,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -324,7 +341,7 @@ func (b *Bitstamp) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) (
|
||||
func (b *Bitstamp) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
|
||||
var currPair string
|
||||
if len(getOrdersRequest.Currencies) == 1 {
|
||||
currPair = getOrdersRequest.Currencies[0].Pair().String()
|
||||
currPair = getOrdersRequest.Currencies[0].String()
|
||||
}
|
||||
resp, err := b.GetUserTransactions(currPair)
|
||||
if err != nil {
|
||||
@@ -336,30 +353,31 @@ func (b *Bitstamp) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) (
|
||||
if order.Type != 2 {
|
||||
continue
|
||||
}
|
||||
quoteCurrency := ""
|
||||
baseCurrency := ""
|
||||
var quoteCurrency, baseCurrency currency.Code
|
||||
|
||||
switch {
|
||||
case order.BTC > 0:
|
||||
baseCurrency = symbol.BTC
|
||||
baseCurrency = currency.BTC
|
||||
case order.XRP > 0:
|
||||
baseCurrency = symbol.XRP
|
||||
baseCurrency = currency.XRP
|
||||
default:
|
||||
log.Warnf("no base currency found for OrderID '%v'", order.OrderID)
|
||||
}
|
||||
|
||||
switch {
|
||||
case order.USD > 0:
|
||||
quoteCurrency = symbol.USD
|
||||
quoteCurrency = currency.USD
|
||||
case order.EUR > 0:
|
||||
quoteCurrency = symbol.EUR
|
||||
quoteCurrency = currency.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)
|
||||
var currPair currency.Pair
|
||||
if quoteCurrency.String() != "" && baseCurrency.String() != "" {
|
||||
currPair = currency.NewPairWithDelimiter(baseCurrency.String(),
|
||||
quoteCurrency.String(),
|
||||
b.ConfigCurrencyPairFormat.Delimiter)
|
||||
}
|
||||
orderDate := time.Unix(order.Date, 0)
|
||||
|
||||
@@ -371,7 +389,8 @@ func (b *Bitstamp) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) (
|
||||
})
|
||||
}
|
||||
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
|
||||
|
||||
return orders, nil
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -99,9 +100,9 @@ func (b *Bittrex) Setup(exch config.ExchangeConfig) {
|
||||
b.SetHTTPClientUserAgent(exch.HTTPUserAgent)
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
err := b.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -528,7 +529,7 @@ func (b *Bittrex) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
case exchange.CryptocurrencyTradeFee:
|
||||
fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount)
|
||||
case exchange.CryptocurrencyWithdrawalFee:
|
||||
fee, err = b.GetWithdrawalFee(feeBuilder.FirstCurrency)
|
||||
fee, err = b.GetWithdrawalFee(feeBuilder.Pair.Base)
|
||||
}
|
||||
if fee < 0 {
|
||||
fee = 0
|
||||
@@ -537,7 +538,7 @@ func (b *Bittrex) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
}
|
||||
|
||||
// GetWithdrawalFee returns the fee for withdrawing from the exchange
|
||||
func (b *Bittrex) GetWithdrawalFee(currency string) (float64, error) {
|
||||
func (b *Bittrex) GetWithdrawalFee(c currency.Code) (float64, error) {
|
||||
var fee float64
|
||||
|
||||
currencies, err := b.GetCurrencies()
|
||||
@@ -545,7 +546,7 @@ func (b *Bittrex) GetWithdrawalFee(currency string) (float64, error) {
|
||||
return 0, err
|
||||
}
|
||||
for _, result := range currencies.Result {
|
||||
if result.Currency == currency {
|
||||
if result.Currency == c.String() {
|
||||
fee = result.TxFee
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -222,13 +221,10 @@ func TestGetDepositHistory(t *testing.T) {
|
||||
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +284,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -297,7 +293,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.HKD
|
||||
feeBuilder.FiatCurrency = currency.HKD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -320,8 +316,9 @@ func TestGetActiveOrders(t *testing.T) {
|
||||
TestSetup(t)
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.LTC)},
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []currency.Pair{currency.NewPair(currency.LTC,
|
||||
currency.BTC)},
|
||||
}
|
||||
|
||||
getOrdersRequest.Currencies[0].Delimiter = "-"
|
||||
@@ -368,10 +365,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "-",
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "-",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.LTC,
|
||||
}
|
||||
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -389,7 +386,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -415,7 +412,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -450,7 +447,7 @@ func TestWithdraw(t *testing.T) {
|
||||
TestSetup(t)
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.LTC,
|
||||
Currency: currency.LTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
@@ -502,12 +499,12 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if areTestAPIKeysSet() {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -36,19 +36,23 @@ func (b *Bittrex) Run() {
|
||||
log.Errorf("%s Failed to get available symbols.\n", b.GetName())
|
||||
} else {
|
||||
forceUpgrade := false
|
||||
if !common.StringDataContains(b.EnabledPairs, "-") || !common.StringDataContains(b.AvailablePairs, "-") {
|
||||
if !common.StringDataContains(b.EnabledPairs.Strings(), "-") ||
|
||||
!common.StringDataContains(b.AvailablePairs.Strings(), "-") {
|
||||
forceUpgrade = true
|
||||
}
|
||||
var currencies []string
|
||||
for x := range exchangeProducts.Result {
|
||||
if !exchangeProducts.Result[x].IsActive || exchangeProducts.Result[x].MarketName == "" {
|
||||
if !exchangeProducts.Result[x].IsActive ||
|
||||
exchangeProducts.Result[x].MarketName == "" {
|
||||
continue
|
||||
}
|
||||
currencies = append(currencies, exchangeProducts.Result[x].MarketName)
|
||||
}
|
||||
|
||||
if forceUpgrade {
|
||||
enabledPairs := []string{"USDT-BTC"}
|
||||
enabledPairs := currency.Pairs{currency.Pair{Base: currency.USDT,
|
||||
Quote: currency.BTC, Delimiter: "-"}}
|
||||
|
||||
log.Warn("Available pairs for Bittrex reset due to config upgrade, please enable the ones you would like again")
|
||||
|
||||
err = b.UpdateCurrencies(enabledPairs, true, true)
|
||||
@@ -56,7 +60,14 @@ func (b *Bittrex) Run() {
|
||||
log.Errorf("%s Failed to get config.", b.GetName())
|
||||
}
|
||||
}
|
||||
err = b.UpdateCurrencies(currencies, false, forceUpgrade)
|
||||
|
||||
var newCurrencies currency.Pairs
|
||||
for _, p := range currencies {
|
||||
newCurrencies = append(newCurrencies,
|
||||
currency.NewPairFromString(p))
|
||||
}
|
||||
|
||||
err = b.UpdateCurrencies(newCurrencies, false, forceUpgrade)
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to get config.", b.GetName())
|
||||
}
|
||||
@@ -76,7 +87,7 @@ func (b *Bittrex) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
var currencies []exchange.AccountCurrencyInfo
|
||||
for i := 0; i < len(accountBalance.Result); i++ {
|
||||
var exchangeCurrency exchange.AccountCurrencyInfo
|
||||
exchangeCurrency.CurrencyName = accountBalance.Result[i].Currency
|
||||
exchangeCurrency.CurrencyName = currency.NewCode(accountBalance.Result[i].Currency)
|
||||
exchangeCurrency.TotalValue = accountBalance.Result[i].Balance
|
||||
exchangeCurrency.Hold = accountBalance.Result[i].Balance - accountBalance.Result[i].Available
|
||||
currencies = append(currencies, exchangeCurrency)
|
||||
@@ -90,7 +101,7 @@ func (b *Bittrex) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *Bittrex) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bittrex) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
tick, err := b.GetMarketSummaries()
|
||||
if err != nil {
|
||||
@@ -110,14 +121,14 @@ func (b *Bittrex) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Pr
|
||||
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)
|
||||
ticker.ProcessTicker(b.GetName(), tickerPrice, assetType)
|
||||
}
|
||||
}
|
||||
return ticker.GetTicker(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (b *Bittrex) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *Bittrex) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tick, err := ticker.GetTicker(b.GetName(), p, ticker.Spot)
|
||||
if err != nil {
|
||||
return b.UpdateTicker(p, assetType)
|
||||
@@ -126,8 +137,8 @@ func (b *Bittrex) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns the orderbook for a currency pair
|
||||
func (b *Bittrex) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
|
||||
func (b *Bittrex) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateOrderbook(p, assetType)
|
||||
}
|
||||
@@ -135,7 +146,7 @@ func (b *Bittrex) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbo
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *Bittrex) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (b *Bittrex) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
orderbookNew, err := b.GetOrderbook(exchange.FormatExchangeCurrency(b.GetName(), p).String())
|
||||
if err != nil {
|
||||
@@ -160,8 +171,16 @@ func (b *Bittrex) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderb
|
||||
)
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(b.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = b.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetFundingHistory returns funding history, deposits and
|
||||
@@ -172,14 +191,14 @@ func (b *Bittrex) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *Bittrex) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *Bittrex) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (b *Bittrex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
func (b *Bittrex) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
buy := side == exchange.BuyOrderSide
|
||||
var response UUID
|
||||
@@ -190,9 +209,9 @@ func (b *Bittrex) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orde
|
||||
}
|
||||
|
||||
if buy {
|
||||
response, err = b.PlaceBuyLimit(p.Pair().String(), amount, price)
|
||||
response, err = b.PlaceBuyLimit(p.String(), amount, price)
|
||||
} else {
|
||||
response, err = b.PlaceSellLimit(p.Pair().String(), amount, price)
|
||||
response, err = b.PlaceSellLimit(p.String(), amount, price)
|
||||
}
|
||||
|
||||
if response.Result.ID != "" {
|
||||
@@ -246,7 +265,7 @@ func (b *Bittrex) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *Bittrex) GetDepositAddress(cryptocurrency pair.CurrencyItem, _ string) (string, error) {
|
||||
func (b *Bittrex) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) {
|
||||
depositAddr, err := b.GetCryptoDepositAddress(cryptocurrency.String())
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -289,7 +308,7 @@ func (b *Bittrex) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, error)
|
||||
func (b *Bittrex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
|
||||
var currPair string
|
||||
if len(getOrdersRequest.Currencies) == 1 {
|
||||
currPair = getOrdersRequest.Currencies[0].Pair().String()
|
||||
currPair = getOrdersRequest.Currencies[0].String()
|
||||
}
|
||||
|
||||
resp, err := b.GetOpenOrders(currPair)
|
||||
@@ -305,7 +324,8 @@ func (b *Bittrex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
b.Name, "GetActiveOrders", order.OrderUUID, order.Opened)
|
||||
}
|
||||
|
||||
currency := pair.NewCurrencyPairDelimiter(order.Exchange, b.ConfigCurrencyPairFormat.Delimiter)
|
||||
pair := currency.NewPairDelimiter(order.Exchange,
|
||||
b.ConfigCurrencyPairFormat.Delimiter)
|
||||
orderType := exchange.OrderType(strings.ToUpper(order.Type))
|
||||
|
||||
orders = append(orders, exchange.OrderDetail{
|
||||
@@ -316,12 +336,13 @@ func (b *Bittrex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
ID: order.OrderUUID,
|
||||
Exchange: b.Name,
|
||||
OrderType: orderType,
|
||||
CurrencyPair: currency,
|
||||
CurrencyPair: pair,
|
||||
})
|
||||
}
|
||||
|
||||
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
|
||||
|
||||
return orders, nil
|
||||
@@ -332,7 +353,7 @@ func (b *Bittrex) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
func (b *Bittrex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
|
||||
var currPair string
|
||||
if len(getOrdersRequest.Currencies) == 1 {
|
||||
currPair = getOrdersRequest.Currencies[0].Pair().String()
|
||||
currPair = getOrdersRequest.Currencies[0].String()
|
||||
}
|
||||
|
||||
resp, err := b.GetOrderHistoryForCurrency(currPair)
|
||||
@@ -348,7 +369,8 @@ func (b *Bittrex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
b.Name, "GetActiveOrders", order.OrderUUID, order.Opened)
|
||||
}
|
||||
|
||||
currency := pair.NewCurrencyPairDelimiter(order.Exchange, b.ConfigCurrencyPairFormat.Delimiter)
|
||||
pair := currency.NewPairDelimiter(order.Exchange,
|
||||
b.ConfigCurrencyPairFormat.Delimiter)
|
||||
orderType := exchange.OrderType(strings.ToUpper(order.Type))
|
||||
|
||||
orders = append(orders, exchange.OrderDetail{
|
||||
@@ -360,12 +382,13 @@ func (b *Bittrex) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([
|
||||
Exchange: b.Name,
|
||||
OrderType: orderType,
|
||||
Fee: order.Commission,
|
||||
CurrencyPair: currency,
|
||||
CurrencyPair: pair,
|
||||
})
|
||||
}
|
||||
|
||||
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByCurrencies(&orders, getOrdersRequest.Currencies)
|
||||
|
||||
return orders, nil
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -60,9 +61,9 @@ func (b *BTCC) Setup(exch config.ExchangeConfig) {
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.Websocket.SetWsStatusAndConnection(exch.Websocket)
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
err := b.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -100,9 +101,9 @@ func (b *BTCC) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
|
||||
switch feeBuilder.FeeType {
|
||||
case exchange.CryptocurrencyWithdrawalFee:
|
||||
fee = getCryptocurrencyWithdrawalFee(feeBuilder.FirstCurrency)
|
||||
fee = getCryptocurrencyWithdrawalFee(feeBuilder.Pair.Base)
|
||||
case exchange.InternationalBankWithdrawalFee:
|
||||
fee = getInternationalBankWithdrawalFee(feeBuilder.CurrencyItem, feeBuilder.Amount)
|
||||
fee = getInternationalBankWithdrawalFee(feeBuilder.FiatCurrency, feeBuilder.Amount)
|
||||
}
|
||||
if fee < 0 {
|
||||
fee = 0
|
||||
@@ -110,10 +111,10 @@ func (b *BTCC) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
func getCryptocurrencyWithdrawalFee(currency string) float64 {
|
||||
return WithdrawalFees[currency]
|
||||
func getCryptocurrencyWithdrawalFee(c currency.Code) float64 {
|
||||
return WithdrawalFees[c]
|
||||
}
|
||||
|
||||
func getInternationalBankWithdrawalFee(currency string, amount float64) float64 {
|
||||
return WithdrawalFees[currency] * amount
|
||||
func getInternationalBankWithdrawalFee(c currency.Code, amount float64) float64 {
|
||||
return WithdrawalFees[c] * amount
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -78,13 +77,10 @@ func TestSetup(t *testing.T) {
|
||||
// }
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +140,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.USD
|
||||
feeBuilder.FiatCurrency = currency.USD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -153,7 +149,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.USD
|
||||
feeBuilder.FiatCurrency = currency.USD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.005) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.005), resp)
|
||||
t.Error(err)
|
||||
@@ -221,10 +217,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "-",
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "-",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.LTC,
|
||||
}
|
||||
_, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 1, "clientId")
|
||||
if err != common.ErrNotYetImplemented {
|
||||
@@ -240,7 +236,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -263,7 +259,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -284,7 +280,7 @@ func TestWithdraw(t *testing.T) {
|
||||
TestSetup(t)
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.LTC,
|
||||
Currency: currency.LTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package btcc
|
||||
|
||||
import "encoding/json"
|
||||
import "github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
)
|
||||
|
||||
// WsAllTickerData defines multiple ticker data
|
||||
type WsAllTickerData []WsTicker
|
||||
@@ -84,12 +87,12 @@ type WsTicker struct {
|
||||
|
||||
// WithdrawalFees the large list of predefined withdrawal fees
|
||||
// Prone to change
|
||||
var WithdrawalFees = map[string]float64{
|
||||
symbol.USD: 0.005,
|
||||
symbol.USDT: 10,
|
||||
symbol.BTC: 0.001,
|
||||
symbol.ETH: 0.01,
|
||||
symbol.BCH: 0.0001,
|
||||
symbol.LTC: 0.001,
|
||||
symbol.DASH: 0.002,
|
||||
var WithdrawalFees = map[currency.Code]float64{
|
||||
currency.USD: 0.005,
|
||||
currency.USDT: 10,
|
||||
currency.BTC: 0.001,
|
||||
currency.ETH: 0.01,
|
||||
currency.BCH: 0.0001,
|
||||
currency.LTC: 0.001,
|
||||
currency.DASH: 0.002,
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
@@ -221,7 +221,7 @@ func (b *BTCC) WsHandleData() {
|
||||
tick.HighPrice = ticker.High
|
||||
tick.LowPrice = ticker.Low
|
||||
tick.OpenPrice = ticker.Open
|
||||
tick.Pair = pair.NewCurrencyPairFromString(ticker.Symbol)
|
||||
tick.Pair = currency.NewPairFromString(ticker.Symbol)
|
||||
tick.Quantity = ticker.Volume
|
||||
timestamp := time.Unix(ticker.Timestamp, 0)
|
||||
tick.Timestamp = timestamp
|
||||
@@ -300,9 +300,10 @@ func (b *BTCC) WsUpdateCurrencyPairs() error {
|
||||
return err
|
||||
}
|
||||
|
||||
var availableTickers []string
|
||||
var availableTickers currency.Pairs
|
||||
for _, tickerData := range tickers {
|
||||
availableTickers = append(availableTickers, tickerData.Symbol)
|
||||
availableTickers = append(availableTickers,
|
||||
currency.NewPairFromString(tickerData.Symbol))
|
||||
}
|
||||
|
||||
err = b.UpdateCurrencies(availableTickers, false, true)
|
||||
@@ -407,9 +408,7 @@ func (b *BTCC) WsProcessOrderbookSnapshot(ob WsOrderbookSnapshot) error {
|
||||
newOrderbook.Asks = asks
|
||||
newOrderbook.AssetType = "SPOT"
|
||||
newOrderbook.Bids = bids
|
||||
newOrderbook.CurrencyPair = ob.Symbol
|
||||
newOrderbook.LastUpdated = time.Now()
|
||||
newOrderbook.Pair = pair.NewCurrencyPairFromString(ob.Symbol)
|
||||
newOrderbook.Pair = currency.NewPairFromString(ob.Symbol)
|
||||
|
||||
err := b.Websocket.Orderbook.LoadSnapshot(newOrderbook, b.GetName(), false)
|
||||
if err != nil {
|
||||
@@ -419,7 +418,7 @@ func (b *BTCC) WsProcessOrderbookSnapshot(ob WsOrderbookSnapshot) error {
|
||||
b.Websocket.DataHandler <- exchange.WebsocketOrderbookUpdate{
|
||||
Exchange: b.GetName(),
|
||||
Asset: "SPOT",
|
||||
Pair: pair.NewCurrencyPairFromString(ob.Symbol),
|
||||
Pair: currency.NewPairFromString(ob.Symbol),
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -458,7 +457,7 @@ func (b *BTCC) WsProcessOrderbookUpdate(ob WsOrderbookSnapshot) error {
|
||||
bids = append(bids, orderbook.Item{Price: data.Price, Amount: newSize})
|
||||
}
|
||||
|
||||
p := pair.NewCurrencyPairFromString(ob.Symbol)
|
||||
p := currency.NewPairFromString(ob.Symbol)
|
||||
|
||||
err := b.Websocket.Orderbook.Update(bids, asks, p, time.Now(), b.GetName(), "SPOT")
|
||||
if err != nil {
|
||||
@@ -468,7 +467,7 @@ func (b *BTCC) WsProcessOrderbookUpdate(ob WsOrderbookSnapshot) error {
|
||||
b.Websocket.DataHandler <- exchange.WebsocketOrderbookUpdate{
|
||||
Exchange: b.GetName(),
|
||||
Asset: "SPOT",
|
||||
Pair: pair.NewCurrencyPairFromString(ob.Symbol),
|
||||
Pair: currency.NewPairFromString(ob.Symbol),
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -545,7 +544,8 @@ func (b *BTCC) WsProcessOldOrderbookSnapshot(ob WsOrderbookSnapshotOld, symbol s
|
||||
})
|
||||
}
|
||||
|
||||
p := pair.NewCurrencyPairFromString(symbol)
|
||||
p := currency.NewPairFromString(symbol)
|
||||
|
||||
err := b.Websocket.Orderbook.Update(bids, asks, p, time.Now(), b.GetName(), "SPOT")
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -29,9 +29,12 @@ func (b *BTCC) Run() {
|
||||
log.Debugf("%s %d currencies enabled: %s.\n", b.GetName(), len(b.EnabledPairs), b.EnabledPairs)
|
||||
}
|
||||
|
||||
if common.StringDataContains(b.EnabledPairs, "CNY") || common.StringDataContains(b.AvailablePairs, "CNY") || common.StringDataContains(b.BaseCurrencies, "CNY") {
|
||||
if common.StringDataContains(b.EnabledPairs.Strings(), "CNY") ||
|
||||
common.StringDataContains(b.AvailablePairs.Strings(), "CNY") ||
|
||||
common.StringDataContains(b.BaseCurrencies.Strings(), "CNY") {
|
||||
log.Warn("BTCC only supports BTCUSD now, upgrading available, enabled and base currencies to BTCUSD/USD")
|
||||
pairs := []string{"BTCUSD"}
|
||||
pairs := currency.Pairs{currency.Pair{Base: currency.BTC,
|
||||
Quote: currency.USD}}
|
||||
cfg := config.GetConfig()
|
||||
exchCfg, err := cfg.GetExchangeConfig(b.Name)
|
||||
if err != nil {
|
||||
@@ -39,10 +42,10 @@ func (b *BTCC) Run() {
|
||||
return
|
||||
}
|
||||
|
||||
exchCfg.BaseCurrencies = "USD"
|
||||
exchCfg.AvailablePairs = pairs[0]
|
||||
exchCfg.EnabledPairs = pairs[0]
|
||||
b.BaseCurrencies = []string{"USD"}
|
||||
exchCfg.BaseCurrencies = currency.Currencies{currency.USD}
|
||||
exchCfg.AvailablePairs = pairs
|
||||
exchCfg.EnabledPairs = pairs
|
||||
b.BaseCurrencies = currency.Currencies{currency.USD}
|
||||
|
||||
err = b.UpdateCurrencies(pairs, false, true)
|
||||
if err != nil {
|
||||
@@ -63,22 +66,22 @@ 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) {
|
||||
func (b *BTCC) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
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) {
|
||||
func (b *BTCC) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
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) {
|
||||
func (b *BTCC) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
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) {
|
||||
func (b *BTCC) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
return orderbook.Base{}, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
@@ -95,12 +98,12 @@ func (b *BTCC) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *BTCC) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *BTCC) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
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) {
|
||||
func (b *BTCC) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
|
||||
return exchange.SubmitOrderResponse{}, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
@@ -126,7 +129,7 @@ func (b *BTCC) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *BTCC) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
|
||||
func (b *BTCC) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) {
|
||||
return "", common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -89,9 +89,9 @@ func (b *BTCMarkets) Setup(exch config.ExchangeConfig) {
|
||||
b.SetHTTPClientUserAgent(exch.HTTPUserAgent)
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
err := b.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -287,7 +287,6 @@ func (b *BTCMarkets) GetOrders(currency, instrument string, limit, since int64,
|
||||
func (b *BTCMarkets) GetOpenOrders() ([]Order, error) {
|
||||
type marketsResp struct {
|
||||
Response
|
||||
Orders []Order `json:"orders"`
|
||||
}
|
||||
req := make(map[string]interface{})
|
||||
var resp marketsResp
|
||||
@@ -369,9 +368,9 @@ func (b *BTCMarkets) GetAccountBalance() ([]AccountBalance, error) {
|
||||
}
|
||||
|
||||
// GetTradingFee returns the account's trading fee for a currency pair
|
||||
func (b *BTCMarkets) GetTradingFee(firstPair, secondPair string) (TradingFee, error) {
|
||||
func (b *BTCMarkets) GetTradingFee(base, quote currency.Code) (TradingFee, error) {
|
||||
var tradingFee TradingFee
|
||||
path := fmt.Sprintf(btcMarketsTradingFee, firstPair, secondPair)
|
||||
path := fmt.Sprintf(btcMarketsTradingFee, base, quote)
|
||||
return tradingFee, b.SendAuthenticatedRequest(http.MethodGet, path, nil, &tradingFee)
|
||||
}
|
||||
|
||||
@@ -386,7 +385,10 @@ func (b *BTCMarkets) WithdrawCrypto(amount float64, currency, address string) (s
|
||||
}
|
||||
|
||||
resp := Response{}
|
||||
err := b.SendAuthenticatedRequest(http.MethodPost, btcMarketsWithdrawCrypto, req, &resp)
|
||||
err := b.SendAuthenticatedRequest(http.MethodPost,
|
||||
btcMarketsWithdrawCrypto,
|
||||
req,
|
||||
&resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -413,7 +415,9 @@ func (b *BTCMarkets) WithdrawAUD(accountName, accountNumber, bankName, bsbNumber
|
||||
}
|
||||
|
||||
resp := Response{}
|
||||
err := b.SendAuthenticatedRequest(http.MethodPost, btcMarketsWithdrawAud, req, &resp)
|
||||
err := b.SendAuthenticatedRequest(http.MethodPost, btcMarketsWithdrawAud,
|
||||
req,
|
||||
&resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -433,7 +437,8 @@ func (b *BTCMarkets) SendHTTPRequest(path string, result interface{}) error {
|
||||
// SendAuthenticatedRequest sends an authenticated HTTP request
|
||||
func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data, result interface{}) (err error) {
|
||||
if !b.AuthenticatedAPISupport {
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name)
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet,
|
||||
b.Name)
|
||||
}
|
||||
|
||||
if b.Nonce.Get() == 0 {
|
||||
@@ -454,10 +459,14 @@ func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data, result
|
||||
req = path + "\n" + b.Nonce.String()[0:13] + "\n"
|
||||
}
|
||||
|
||||
hmac := common.GetHMAC(common.HashSHA512, []byte(req), []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, req)
|
||||
log.Debugf("Sending %s request to URL %s with params %s\n",
|
||||
reqType,
|
||||
b.APIUrl+path,
|
||||
req)
|
||||
}
|
||||
|
||||
headers := make(map[string]string)
|
||||
@@ -468,7 +477,13 @@ func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data, result
|
||||
headers["timestamp"] = b.Nonce.String()[0:13]
|
||||
headers["signature"] = common.Base64Encode(hmac)
|
||||
|
||||
return b.SendPayload(reqType, b.APIUrl+path, headers, bytes.NewBuffer(payload), result, true, b.Verbose)
|
||||
return b.SendPayload(reqType,
|
||||
b.APIUrl+path,
|
||||
headers,
|
||||
bytes.NewBuffer(payload),
|
||||
result,
|
||||
true,
|
||||
b.Verbose)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
@@ -477,15 +492,20 @@ func (b *BTCMarkets) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
|
||||
switch feeBuilder.FeeType {
|
||||
case exchange.CryptocurrencyTradeFee:
|
||||
tradingFee, err := b.GetTradingFee(feeBuilder.FirstCurrency, feeBuilder.SecondCurrency)
|
||||
tradingFee, err := b.GetTradingFee(feeBuilder.Pair.Base,
|
||||
feeBuilder.Pair.Quote)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
fee = calculateTradingFee(tradingFee, feeBuilder.PurchasePrice, feeBuilder.Amount)
|
||||
|
||||
fee = calculateTradingFee(tradingFee,
|
||||
feeBuilder.PurchasePrice,
|
||||
feeBuilder.Amount)
|
||||
|
||||
case exchange.CryptocurrencyWithdrawalFee:
|
||||
fee = getCryptocurrencyWithdrawalFee(feeBuilder.FirstCurrency)
|
||||
fee = getCryptocurrencyWithdrawalFee(feeBuilder.Pair.Base)
|
||||
case exchange.InternationalBankWithdrawalFee:
|
||||
fee = getInternationalBankWithdrawalFee(feeBuilder.CurrencyItem)
|
||||
fee = getInternationalBankWithdrawalFee(feeBuilder.FiatCurrency)
|
||||
}
|
||||
if fee < 0 {
|
||||
fee = 0
|
||||
@@ -498,14 +518,14 @@ func calculateTradingFee(tradingFee TradingFee, purchasePrice, amount float64) (
|
||||
return fee * amount * purchasePrice
|
||||
}
|
||||
|
||||
func getCryptocurrencyWithdrawalFee(currency string) float64 {
|
||||
return WithdrawalFees[currency]
|
||||
func getCryptocurrencyWithdrawalFee(c currency.Code) float64 {
|
||||
return WithdrawalFees[c]
|
||||
}
|
||||
|
||||
func getInternationalBankWithdrawalFee(currency string) float64 {
|
||||
func getInternationalBankWithdrawalFee(c currency.Code) float64 {
|
||||
var fee float64
|
||||
|
||||
if currency == symbol.AUD {
|
||||
if c == currency.AUD {
|
||||
fee = 0
|
||||
}
|
||||
return fee
|
||||
|
||||
@@ -6,8 +6,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -168,13 +167,10 @@ func TestGetOrderInfo(t *testing.T) {
|
||||
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,7 +183,7 @@ func TestGetFee(t *testing.T) {
|
||||
if apiKey != "" || apiSecret != "" {
|
||||
// CryptocurrencyTradeFee Fiat
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.SecondCurrency = symbol.USD
|
||||
feeBuilder.Pair.Quote = currency.USD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.00849999) || err != nil {
|
||||
t.Error(err)
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.00849999), resp)
|
||||
@@ -245,7 +241,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.AUD
|
||||
feeBuilder.FiatCurrency = currency.AUD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -254,7 +250,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.AUD
|
||||
feeBuilder.FiatCurrency = currency.AUD
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -293,8 +289,9 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
TestSetup(t)
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.LTC)},
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []currency.Pair{currency.NewPair(currency.LTC,
|
||||
currency.BTC)},
|
||||
}
|
||||
|
||||
_, err := b.GetOrderHistory(getOrdersRequest)
|
||||
@@ -323,10 +320,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "-",
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "-",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.LTC,
|
||||
}
|
||||
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -344,7 +341,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -370,7 +367,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -405,7 +402,7 @@ func TestWithdraw(t *testing.T) {
|
||||
TestSetup(t)
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.LTC,
|
||||
Currency: currency.LTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
@@ -433,7 +430,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.AUD,
|
||||
Currency: currency.AUD,
|
||||
Description: "WITHDRAW IT ALL",
|
||||
BankAccountName: "Satoshi Nakamoto",
|
||||
BankAccountNumber: 12345,
|
||||
@@ -441,7 +438,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
BankCity: "Tarry Town",
|
||||
BankCountry: "Hyrule",
|
||||
BankName: "Commonwealth Bank of Australia",
|
||||
WireCurrency: symbol.AUD,
|
||||
WireCurrency: currency.AUD.String(),
|
||||
SwiftCode: "Taylor",
|
||||
RequiresIntermediaryBank: false,
|
||||
IsExpressWire: false,
|
||||
@@ -473,7 +470,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
_, err := b.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := b.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package btcmarkets
|
||||
|
||||
import "github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
import "github.com/thrasher-/gocryptotrader/currency"
|
||||
|
||||
// Response is the genralized response type
|
||||
type Response struct {
|
||||
@@ -129,14 +129,14 @@ type WithdrawRequestAUD struct {
|
||||
|
||||
// WithdrawalFees the large list of predefined withdrawal fees
|
||||
// Prone to change
|
||||
var WithdrawalFees = map[string]float64{
|
||||
symbol.AUD: 0,
|
||||
symbol.BTC: 0.001,
|
||||
symbol.ETH: 0.001,
|
||||
symbol.ETC: 0.001,
|
||||
symbol.LTC: 0.0001,
|
||||
symbol.XRP: 0.15,
|
||||
symbol.BCH: 0.0001,
|
||||
symbol.OMG: 0.15,
|
||||
symbol.POWR: 5,
|
||||
var WithdrawalFees = map[currency.Code]float64{
|
||||
currency.AUD: 0,
|
||||
currency.BTC: 0.001,
|
||||
currency.ETH: 0.001,
|
||||
currency.ETC: 0.001,
|
||||
currency.LTC: 0.0001,
|
||||
currency.XRP: 0.15,
|
||||
currency.BCH: 0.0001,
|
||||
currency.OMG: 0.15,
|
||||
currency.POWR: 5,
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -38,17 +37,22 @@ func (b *BTCMarkets) Run() {
|
||||
log.Errorf("%s failed to get active market. Err: %s", b.Name, err)
|
||||
} else {
|
||||
forceUpgrade := false
|
||||
if !common.StringDataContains(b.EnabledPairs, "-") || !common.StringDataContains(b.AvailablePairs, "-") {
|
||||
if !common.StringDataContains(b.EnabledPairs.Strings(), "-") ||
|
||||
!common.StringDataContains(b.AvailablePairs.Strings(), "-") {
|
||||
forceUpgrade = true
|
||||
}
|
||||
|
||||
var currencies []string
|
||||
var currencies currency.Pairs
|
||||
for x := range markets {
|
||||
currencies = append(currencies, markets[x].Instrument+"-"+markets[x].Currency)
|
||||
currencies = append(currencies,
|
||||
currency.NewPairWithDelimiter(markets[x].Instrument,
|
||||
markets[x].Currency, "-"))
|
||||
}
|
||||
|
||||
if forceUpgrade {
|
||||
enabledPairs := []string{"BTC-AUD"}
|
||||
enabledPairs := currency.Pairs{currency.Pair{Base: currency.BTC,
|
||||
Quote: currency.AUD, Delimiter: "-"}}
|
||||
|
||||
log.Warn("Available pairs for BTC Makrets reset due to config upgrade, please enable the pairs you would like again.")
|
||||
|
||||
err = b.UpdateCurrencies(enabledPairs, true, true)
|
||||
@@ -64,10 +68,9 @@ func (b *BTCMarkets) Run() {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *BTCMarkets) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *BTCMarkets) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
tick, err := b.GetTicker(p.FirstCurrency.String(),
|
||||
p.SecondCurrency.String())
|
||||
tick, err := b.GetTicker(p.Base.String(), p.Quote.String())
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
@@ -75,12 +78,17 @@ func (b *BTCMarkets) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker
|
||||
tickerPrice.Ask = tick.BestAsk
|
||||
tickerPrice.Bid = tick.BestBID
|
||||
tickerPrice.Last = tick.LastPrice
|
||||
ticker.ProcessTicker(b.GetName(), p, tickerPrice, assetType)
|
||||
|
||||
err = ticker.ProcessTicker(b.GetName(), tickerPrice, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
|
||||
return ticker.GetTicker(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (b *BTCMarkets) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *BTCMarkets) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tickerNew, err := ticker.GetTicker(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateTicker(p, assetType)
|
||||
@@ -89,8 +97,8 @@ func (b *BTCMarkets) GetTickerPrice(p pair.CurrencyPair, assetType string) (tick
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns orderbook base on the currency pair
|
||||
func (b *BTCMarkets) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
|
||||
func (b *BTCMarkets) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateOrderbook(p, assetType)
|
||||
}
|
||||
@@ -98,10 +106,10 @@ func (b *BTCMarkets) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orde
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *BTCMarkets) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (b *BTCMarkets) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
orderbookNew, err := b.GetOrderbook(p.FirstCurrency.String(),
|
||||
p.SecondCurrency.String())
|
||||
orderbookNew, err := b.GetOrderbook(p.Base.String(),
|
||||
p.Quote.String())
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
@@ -116,8 +124,16 @@ func (b *BTCMarkets) UpdateOrderbook(p pair.CurrencyPair, assetType string) (ord
|
||||
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data[1], Price: data[0]})
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(b.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(b.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = b.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetAccountInfo retrieves balances for all enabled currencies for the
|
||||
@@ -134,7 +150,7 @@ func (b *BTCMarkets) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
var currencies []exchange.AccountCurrencyInfo
|
||||
for i := 0; i < len(accountBalance); i++ {
|
||||
var exchangeCurrency exchange.AccountCurrencyInfo
|
||||
exchangeCurrency.CurrencyName = accountBalance[i].Currency
|
||||
exchangeCurrency.CurrencyName = currency.NewCode(accountBalance[i].Currency)
|
||||
exchangeCurrency.TotalValue = accountBalance[i].Balance
|
||||
exchangeCurrency.Hold = accountBalance[i].PendingFunds
|
||||
|
||||
@@ -156,16 +172,22 @@ func (b *BTCMarkets) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *BTCMarkets) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *BTCMarkets) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (b *BTCMarkets) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
|
||||
func (b *BTCMarkets) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
response, err := b.NewOrder(p.FirstCurrency.Upper().String(), p.SecondCurrency.Upper().String(), price, amount, side.ToString(), orderType.ToString(), clientID)
|
||||
response, err := b.NewOrder(p.Base.Upper().String(),
|
||||
p.Quote.Upper().String(),
|
||||
price,
|
||||
amount,
|
||||
side.ToString(),
|
||||
orderType.ToString(),
|
||||
clientID)
|
||||
|
||||
if response > 0 {
|
||||
submitOrderResponse.OrderID = fmt.Sprintf("%v", response)
|
||||
@@ -270,14 +292,16 @@ func (b *BTCMarkets) GetOrderInfo(orderID string) (exchange.OrderDetail, error)
|
||||
OrderDetail.OrderType = orderType
|
||||
OrderDetail.Price = order.Price
|
||||
OrderDetail.Status = order.Status
|
||||
OrderDetail.CurrencyPair = pair.NewCurrencyPairWithDelimiter(order.Instrument, order.Currency, b.ConfigCurrencyPairFormat.Delimiter)
|
||||
OrderDetail.CurrencyPair = currency.NewPairWithDelimiter(order.Instrument,
|
||||
order.Currency,
|
||||
b.ConfigCurrencyPairFormat.Delimiter)
|
||||
}
|
||||
|
||||
return OrderDetail, nil
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *BTCMarkets) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
|
||||
func (b *BTCMarkets) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) {
|
||||
return "", common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
@@ -289,7 +313,7 @@ func (b *BTCMarkets) WithdrawCryptocurrencyFunds(withdrawRequest exchange.Withdr
|
||||
// WithdrawFiatFunds returns a withdrawal ID when a
|
||||
// withdrawal is submitted
|
||||
func (b *BTCMarkets) WithdrawFiatFunds(withdrawRequest exchange.WithdrawRequest) (string, error) {
|
||||
if withdrawRequest.Currency != symbol.AUD {
|
||||
if withdrawRequest.Currency != currency.AUD {
|
||||
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)
|
||||
@@ -339,7 +363,9 @@ func (b *BTCMarkets) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest)
|
||||
OrderType: orderType,
|
||||
Price: order.Price,
|
||||
Status: order.Status,
|
||||
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.Instrument, order.Currency, b.ConfigCurrencyPairFormat.Delimiter),
|
||||
CurrencyPair: currency.NewPairWithDelimiter(order.Instrument,
|
||||
order.Currency,
|
||||
b.ConfigCurrencyPairFormat.Delimiter),
|
||||
}
|
||||
|
||||
for _, trade := range order.Trades {
|
||||
@@ -359,7 +385,8 @@ func (b *BTCMarkets) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest)
|
||||
}
|
||||
|
||||
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
|
||||
|
||||
return orders, nil
|
||||
@@ -374,7 +401,11 @@ func (b *BTCMarkets) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest)
|
||||
|
||||
var respOrders []Order
|
||||
for _, currency := range getOrdersRequest.Currencies {
|
||||
resp, err := b.GetOrders(currency.FirstCurrency.String(), currency.SecondCurrency.String(), 200, 0, true)
|
||||
resp, err := b.GetOrders(currency.Base.String(),
|
||||
currency.Quote.String(),
|
||||
200,
|
||||
0,
|
||||
true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -402,7 +433,9 @@ func (b *BTCMarkets) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest)
|
||||
OrderType: orderType,
|
||||
Price: order.Price,
|
||||
Status: order.Status,
|
||||
CurrencyPair: pair.NewCurrencyPairWithDelimiter(order.Instrument, order.Currency, b.ConfigCurrencyPairFormat.Delimiter),
|
||||
CurrencyPair: currency.NewPairWithDelimiter(order.Instrument,
|
||||
order.Currency,
|
||||
b.ConfigCurrencyPairFormat.Delimiter),
|
||||
}
|
||||
|
||||
for _, trade := range order.Trades {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -82,9 +82,9 @@ func (b *BTSE) Setup(exch config.ExchangeConfig) {
|
||||
b.RESTPollingDelay = exch.RESTPollingDelay
|
||||
b.Verbose = exch.Verbose
|
||||
b.Websocket.SetWsStatusAndConnection(exch.Websocket)
|
||||
b.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
b.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
b.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
b.BaseCurrencies = exch.BaseCurrencies
|
||||
b.AvailablePairs = exch.AvailablePairs
|
||||
b.EnabledPairs = exch.EnabledPairs
|
||||
err := b.SetCurrencyPairFormat()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -312,9 +312,9 @@ func (b *BTSE) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
case exchange.CryptocurrencyTradeFee:
|
||||
fee = calculateTradingFee(feeBuilder.IsMaker)
|
||||
case exchange.CryptocurrencyWithdrawalFee:
|
||||
if feeBuilder.FirstCurrency == symbol.BTC {
|
||||
if feeBuilder.Pair.Base.Match(currency.BTC) {
|
||||
fee = 0.0005
|
||||
} else if feeBuilder.FirstCurrency == symbol.USDT {
|
||||
} else if feeBuilder.Pair.Base.Match(currency.USDT) {
|
||||
fee = 5
|
||||
}
|
||||
case exchange.InternationalBankDepositFee:
|
||||
|
||||
@@ -5,8 +5,7 @@ import (
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -146,11 +145,10 @@ func TestGetFee(t *testing.T) {
|
||||
TestSetup(t)
|
||||
|
||||
feeBuilder := exchange.FeeBuilder{
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: "BTC",
|
||||
SecondCurrency: "USD",
|
||||
IsMaker: true,
|
||||
Amount: 1000,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.USD),
|
||||
IsMaker: true,
|
||||
Amount: 1000,
|
||||
}
|
||||
|
||||
if resp, err := b.GetFee(feeBuilder); resp != 0.00050 || err != nil {
|
||||
@@ -170,7 +168,7 @@ func TestGetFee(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
feeBuilder.FirstCurrency = "USDT"
|
||||
feeBuilder.Pair.Base = currency.USDT
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(5) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(5), resp)
|
||||
t.Error(err)
|
||||
@@ -227,10 +225,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "",
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.USD,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.USD,
|
||||
}
|
||||
response, err := b.SubmitOrder(p, exchange.SellOrderSide, exchange.LimitOrderType, 0.01, 1000000, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -248,7 +246,9 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPairWithDelimiter(symbol.BTC, symbol.USD, "-")
|
||||
currencyPair := currency.NewPairWithDelimiter(currency.BTC.String(),
|
||||
currency.USD.String(),
|
||||
"-")
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "0b66ccaf-dfd4-4b9f-a30b-2380b9c7b66d",
|
||||
@@ -274,7 +274,9 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPairWithDelimiter(symbol.BTC, symbol.USD, "-")
|
||||
currencyPair := currency.NewPairWithDelimiter(currency.BTC.String(),
|
||||
currency.USD.String(),
|
||||
"-")
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
)
|
||||
@@ -28,11 +28,11 @@ func (b *BTSE) WebsocketSubscriber() error {
|
||||
Channels: []websocketChannel{
|
||||
{
|
||||
Name: "snapshot",
|
||||
ProductIDs: b.EnabledPairs,
|
||||
ProductIDs: b.EnabledPairs.Strings(),
|
||||
},
|
||||
{
|
||||
Name: "ticker",
|
||||
ProductIDs: b.EnabledPairs,
|
||||
ProductIDs: b.EnabledPairs.Strings(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -146,7 +146,7 @@ func (b *BTSE) WsHandleData() {
|
||||
|
||||
b.Websocket.DataHandler <- exchange.TickerData{
|
||||
Timestamp: time.Now(),
|
||||
Pair: pair.NewCurrencyPairDelimiter(t.ProductID, "-"),
|
||||
Pair: currency.NewPairDelimiter(t.ProductID, "-"),
|
||||
AssetType: "SPOT",
|
||||
Exchange: b.GetName(),
|
||||
OpenPrice: price,
|
||||
@@ -206,12 +206,16 @@ func (b *BTSE) wsProcessSnapshot(snapshot websocketOrderbookSnapshot) error {
|
||||
orderbook.Item{Price: price, Amount: amount})
|
||||
}
|
||||
|
||||
p := pair.NewCurrencyPairDelimiter(snapshot.ProductID, "-")
|
||||
p := currency.NewPairDelimiter(snapshot.ProductID, "-")
|
||||
base.AssetType = "SPOT"
|
||||
base.Pair = p
|
||||
base.CurrencyPair = snapshot.ProductID
|
||||
base.LastUpdated = time.Now()
|
||||
orderbook.ProcessOrderbook(b.Name, p, base, "SPOT")
|
||||
base.ExchangeName = b.Name
|
||||
|
||||
err := base.Process()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.Websocket.DataHandler <- exchange.WebsocketOrderbookUpdate{
|
||||
Pair: p,
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -40,7 +40,9 @@ func (b *BTSE) Run() {
|
||||
for _, m := range *markets {
|
||||
currencies = append(currencies, m.ID)
|
||||
}
|
||||
err = b.UpdateCurrencies(currencies, false, false)
|
||||
err = b.UpdateCurrencies(currency.NewPairsFromStrings(currencies),
|
||||
false,
|
||||
false)
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to update available currencies.\n", b.Name)
|
||||
}
|
||||
@@ -49,7 +51,7 @@ func (b *BTSE) Run() {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (b *BTSE) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *BTSE) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
|
||||
t, err := b.GetTicker(exchange.FormatExchangeCurrency(b.Name, p).String())
|
||||
@@ -70,12 +72,16 @@ func (b *BTSE) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price
|
||||
tickerPrice.Last = t.Price
|
||||
tickerPrice.Volume = s.Volume
|
||||
tickerPrice.High = s.High
|
||||
ticker.ProcessTicker(b.GetName(), p, tickerPrice, assetType)
|
||||
|
||||
err = ticker.ProcessTicker(b.GetName(), tickerPrice, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
return ticker.GetTicker(b.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (b *BTSE) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (b *BTSE) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tickerNew, err := ticker.GetTicker(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateTicker(p, assetType)
|
||||
@@ -84,8 +90,8 @@ func (b *BTSE) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Pri
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns orderbook base on the currency pair
|
||||
func (b *BTSE) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(b.GetName(), p, assetType)
|
||||
func (b *BTSE) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(b.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return b.UpdateOrderbook(p, assetType)
|
||||
}
|
||||
@@ -93,7 +99,7 @@ func (b *BTSE) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (b *BTSE) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (b *BTSE) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
return orderbook.Base{}, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
@@ -110,7 +116,7 @@ func (b *BTSE) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
for _, b := range *balance {
|
||||
currencies = append(currencies,
|
||||
exchange.AccountCurrencyInfo{
|
||||
CurrencyName: b.Currency,
|
||||
CurrencyName: currency.NewCode(b.Currency),
|
||||
TotalValue: b.Total,
|
||||
Hold: b.Available,
|
||||
},
|
||||
@@ -132,12 +138,12 @@ func (b *BTSE) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (b *BTSE) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (b *BTSE) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
return nil, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (b *BTSE) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
|
||||
func (b *BTSE) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, clientID string) (exchange.SubmitOrderResponse, error) {
|
||||
var resp exchange.SubmitOrderResponse
|
||||
r, err := b.CreateOrder(amount, price, side.ToString(),
|
||||
orderType.ToString(), exchange.FormatExchangeCurrency(b.Name, p).String(), "GTC", clientID)
|
||||
@@ -220,7 +226,7 @@ func (b *BTSE) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
side = exchange.SellOrderSide
|
||||
}
|
||||
|
||||
od.CurrencyPair = pair.NewCurrencyPairDelimiter(o.ProductID,
|
||||
od.CurrencyPair = currency.NewPairDelimiter(o.ProductID,
|
||||
b.ConfigCurrencyPairFormat.Delimiter)
|
||||
od.Exchange = b.Name
|
||||
od.Amount = o.Amount
|
||||
@@ -253,7 +259,7 @@ func (b *BTSE) GetOrderInfo(orderID string) (exchange.OrderDetail, error) {
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *BTSE) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
|
||||
func (b *BTSE) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) {
|
||||
return "", common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
@@ -295,7 +301,7 @@ func (b *BTSE) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]ex
|
||||
}
|
||||
|
||||
openOrder := exchange.OrderDetail{
|
||||
CurrencyPair: pair.NewCurrencyPairDelimiter(order.ProductID,
|
||||
CurrencyPair: currency.NewPairDelimiter(order.ProductID,
|
||||
b.ConfigCurrencyPairFormat.Delimiter),
|
||||
Exchange: b.Name,
|
||||
Amount: order.Amount,
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -104,9 +104,9 @@ func (c *CoinbasePro) Setup(exch config.ExchangeConfig) {
|
||||
c.RESTPollingDelay = exch.RESTPollingDelay
|
||||
c.Verbose = exch.Verbose
|
||||
c.Websocket.SetWsStatusAndConnection(exch.Websocket)
|
||||
c.BaseCurrencies = common.SplitStrings(exch.BaseCurrencies, ",")
|
||||
c.AvailablePairs = common.SplitStrings(exch.AvailablePairs, ",")
|
||||
c.EnabledPairs = common.SplitStrings(exch.EnabledPairs, ",")
|
||||
c.BaseCurrencies = exch.BaseCurrencies
|
||||
c.AvailablePairs = exch.AvailablePairs
|
||||
c.EnabledPairs = exch.EnabledPairs
|
||||
if exch.UseSandbox {
|
||||
c.APIUrl = coinbaseproSandboxAPIURL
|
||||
}
|
||||
@@ -798,7 +798,8 @@ func (c *CoinbasePro) SendHTTPRequest(path string, result interface{}) error {
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP reque
|
||||
func (c *CoinbasePro) SendAuthenticatedHTTPRequest(method, path string, params map[string]interface{}, result interface{}) (err error) {
|
||||
if !c.AuthenticatedAPISupport {
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, c.Name)
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet,
|
||||
c.Name)
|
||||
}
|
||||
|
||||
payload := []byte("")
|
||||
@@ -824,7 +825,13 @@ func (c *CoinbasePro) SendAuthenticatedHTTPRequest(method, path string, params m
|
||||
headers["CB-ACCESS-PASSPHRASE"] = c.ClientID
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
return c.SendPayload(method, c.APIUrl+path, headers, bytes.NewBuffer(payload), result, true, c.Verbose)
|
||||
return c.SendPayload(method,
|
||||
c.APIUrl+path,
|
||||
headers,
|
||||
bytes.NewBuffer(payload),
|
||||
result,
|
||||
true,
|
||||
c.Verbose)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
@@ -836,11 +843,17 @@ func (c *CoinbasePro) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
fee = c.calculateTradingFee(trailingVolume, feeBuilder.FirstCurrency, feeBuilder.Delimiter, feeBuilder.SecondCurrency, feeBuilder.PurchasePrice, feeBuilder.Amount, feeBuilder.IsMaker)
|
||||
fee = c.calculateTradingFee(trailingVolume,
|
||||
feeBuilder.Pair.Base,
|
||||
feeBuilder.Pair.Quote,
|
||||
feeBuilder.Pair.Delimiter,
|
||||
feeBuilder.PurchasePrice,
|
||||
feeBuilder.Amount,
|
||||
feeBuilder.IsMaker)
|
||||
case exchange.InternationalBankWithdrawalFee:
|
||||
fee = getInternationalBankWithdrawalFee(feeBuilder.CurrencyItem)
|
||||
fee = getInternationalBankWithdrawalFee(feeBuilder.FiatCurrency)
|
||||
case exchange.InternationalBankDepositFee:
|
||||
fee = getInternationalBankDepositFee(feeBuilder.CurrencyItem)
|
||||
fee = getInternationalBankDepositFee(feeBuilder.FiatCurrency)
|
||||
}
|
||||
|
||||
if fee < 0 {
|
||||
@@ -850,10 +863,10 @@ func (c *CoinbasePro) GetFee(feeBuilder exchange.FeeBuilder) (float64, error) {
|
||||
return fee, nil
|
||||
}
|
||||
|
||||
func (c *CoinbasePro) calculateTradingFee(trailingVolume []Volume, firstCurrency, delimiter, secondCurrency string, purchasePrice, amount float64, isMaker bool) float64 {
|
||||
func (c *CoinbasePro) calculateTradingFee(trailingVolume []Volume, base, quote currency.Code, delimiter string, purchasePrice, amount float64, isMaker bool) float64 {
|
||||
var fee float64
|
||||
for _, i := range trailingVolume {
|
||||
if strings.EqualFold(i.ProductID, firstCurrency+delimiter+secondCurrency) {
|
||||
if strings.EqualFold(i.ProductID, base.String()+delimiter+quote.String()) {
|
||||
switch {
|
||||
case isMaker:
|
||||
fee = 0
|
||||
@@ -870,24 +883,24 @@ func (c *CoinbasePro) calculateTradingFee(trailingVolume []Volume, firstCurrency
|
||||
return fee * amount * purchasePrice
|
||||
}
|
||||
|
||||
func getInternationalBankWithdrawalFee(currency string) float64 {
|
||||
func getInternationalBankWithdrawalFee(c currency.Code) float64 {
|
||||
var fee float64
|
||||
|
||||
if currency == symbol.USD {
|
||||
if c == currency.USD {
|
||||
fee = 25
|
||||
} else if currency == symbol.EUR {
|
||||
} else if c == currency.EUR {
|
||||
fee = 0.15
|
||||
}
|
||||
|
||||
return fee
|
||||
}
|
||||
|
||||
func getInternationalBankDepositFee(currency string) float64 {
|
||||
func getInternationalBankDepositFee(c currency.Code) float64 {
|
||||
var fee float64
|
||||
|
||||
if currency == symbol.USD {
|
||||
if c == currency.USD {
|
||||
fee = 10
|
||||
} else if currency == symbol.EUR {
|
||||
} else if c == currency.EUR {
|
||||
fee = 0.15
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency/symbol"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
@@ -224,13 +223,10 @@ func TestAuthRequests(t *testing.T) {
|
||||
|
||||
func setFeeBuilder() exchange.FeeBuilder {
|
||||
return exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
Delimiter: "",
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
IsMaker: false,
|
||||
PurchasePrice: 1,
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +288,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
feeBuilder.CurrencyItem = symbol.EUR
|
||||
feeBuilder.FiatCurrency = currency.EUR
|
||||
if resp, err := c.GetFee(feeBuilder); resp != float64(0.15) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -301,7 +297,7 @@ func TestGetFee(t *testing.T) {
|
||||
// InternationalBankWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.CurrencyItem = symbol.USD
|
||||
feeBuilder.FiatCurrency = currency.USD
|
||||
if resp, err := c.GetFee(feeBuilder); resp != float64(25) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
t.Error(err)
|
||||
@@ -318,7 +314,7 @@ func TestCalculateTradingFee(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if resp := c.calculateTradingFee(volume, "btc", "_", "usd", 1, 1, false); resp != float64(0.003) {
|
||||
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.003), resp)
|
||||
}
|
||||
|
||||
@@ -330,7 +326,7 @@ func TestCalculateTradingFee(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if resp := c.calculateTradingFee(volume, "btc", "_", "usd", 1, 1, false); resp != float64(0.003) {
|
||||
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.003), resp)
|
||||
}
|
||||
|
||||
@@ -342,7 +338,7 @@ func TestCalculateTradingFee(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if resp := c.calculateTradingFee(volume, "btc", "_", "usd", 1, 1, false); resp != float64(0.003) {
|
||||
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.003), resp)
|
||||
}
|
||||
|
||||
@@ -354,7 +350,7 @@ func TestCalculateTradingFee(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if resp := c.calculateTradingFee(volume, "btc", "_", "usd", 1, 1, false); resp != float64(0.002) {
|
||||
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.002) {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.002), resp)
|
||||
}
|
||||
|
||||
@@ -366,7 +362,7 @@ func TestCalculateTradingFee(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if resp := c.calculateTradingFee(volume, "btc", "_", "usd", 1, 1, false); resp != float64(0.001) {
|
||||
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.001) {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.001), resp)
|
||||
}
|
||||
|
||||
@@ -378,7 +374,7 @@ func TestCalculateTradingFee(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if resp := c.calculateTradingFee(volume, "btc", "_", "usd", 1, 1, false); resp != float64(0) {
|
||||
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0) {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
}
|
||||
|
||||
@@ -390,7 +386,7 @@ func TestCalculateTradingFee(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
if resp := c.calculateTradingFee(volume, "btc", "_", "usd", 1, 1, true); resp != float64(0) {
|
||||
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, true); resp != float64(0) {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
}
|
||||
}
|
||||
@@ -412,8 +408,9 @@ func TestGetActiveOrders(t *testing.T) {
|
||||
TestSetup(t)
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.LTC)},
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []currency.Pair{currency.NewPair(currency.BTC,
|
||||
currency.LTC)},
|
||||
}
|
||||
|
||||
_, err := c.GetActiveOrders(getOrdersRequest)
|
||||
@@ -429,8 +426,9 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
TestSetup(t)
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []pair.CurrencyPair{pair.NewCurrencyPair(symbol.BTC, symbol.LTC)},
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []currency.Pair{currency.NewPair(currency.BTC,
|
||||
currency.LTC)},
|
||||
}
|
||||
|
||||
_, err := c.GetOrderHistory(getOrdersRequest)
|
||||
@@ -459,10 +457,10 @@ func TestSubmitOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var p = pair.CurrencyPair{
|
||||
Delimiter: "-",
|
||||
FirstCurrency: symbol.BTC,
|
||||
SecondCurrency: symbol.LTC,
|
||||
var p = currency.Pair{
|
||||
Delimiter: "-",
|
||||
Base: currency.BTC,
|
||||
Quote: currency.LTC,
|
||||
}
|
||||
response, err := c.SubmitOrder(p, exchange.BuyOrderSide, exchange.LimitOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
@@ -481,7 +479,7 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -508,7 +506,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := pair.NewCurrencyPair(symbol.LTC, symbol.BTC)
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
@@ -543,7 +541,7 @@ func TestWithdraw(t *testing.T) {
|
||||
TestSetup(t)
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.LTC,
|
||||
Currency: currency.LTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
@@ -571,7 +569,7 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.USD,
|
||||
Currency: currency.USD,
|
||||
BankName: "Federal Reserve Bank",
|
||||
}
|
||||
|
||||
@@ -594,7 +592,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: symbol.USD,
|
||||
Currency: currency.USD,
|
||||
BankName: "Federal Reserve Bank",
|
||||
}
|
||||
|
||||
@@ -608,7 +606,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
_, err := c.GetDepositAddress(symbol.BTC, "")
|
||||
_, err := c.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
)
|
||||
@@ -23,7 +23,7 @@ const (
|
||||
// currencies
|
||||
func (c *CoinbasePro) WebsocketSubscriber() error {
|
||||
currencies := []string{}
|
||||
for _, x := range c.EnabledPairs {
|
||||
for _, x := range c.EnabledPairs.Strings() {
|
||||
currency := x[0:3] + "-" + x[3:]
|
||||
currencies = append(currencies, currency)
|
||||
}
|
||||
@@ -156,7 +156,7 @@ func (c *CoinbasePro) WsHandleData() {
|
||||
|
||||
c.Websocket.DataHandler <- exchange.TickerData{
|
||||
Timestamp: time.Now(),
|
||||
Pair: pair.NewCurrencyPairFromString(ticker.ProductID),
|
||||
Pair: currency.NewPairFromString(ticker.ProductID),
|
||||
AssetType: "SPOT",
|
||||
Exchange: c.GetName(),
|
||||
OpenPrice: ticker.Price,
|
||||
@@ -230,12 +230,9 @@ func (c *CoinbasePro) ProcessSnapshot(snapshot WebsocketOrderbookSnapshot) error
|
||||
orderbook.Item{Price: price, Amount: amount})
|
||||
}
|
||||
|
||||
p := pair.NewCurrencyPairFromString(snapshot.ProductID)
|
||||
|
||||
pair := currency.NewPairFromString(snapshot.ProductID)
|
||||
base.AssetType = "SPOT"
|
||||
base.Pair = p
|
||||
base.CurrencyPair = snapshot.ProductID
|
||||
base.LastUpdated = time.Now()
|
||||
base.Pair = pair
|
||||
|
||||
err := c.Websocket.Orderbook.LoadSnapshot(base, c.GetName(), false)
|
||||
if err != nil {
|
||||
@@ -243,7 +240,7 @@ func (c *CoinbasePro) ProcessSnapshot(snapshot WebsocketOrderbookSnapshot) error
|
||||
}
|
||||
|
||||
c.Websocket.DataHandler <- exchange.WebsocketOrderbookUpdate{
|
||||
Pair: p,
|
||||
Pair: pair,
|
||||
Asset: "SPOT",
|
||||
Exchange: c.GetName(),
|
||||
}
|
||||
@@ -270,7 +267,7 @@ func (c *CoinbasePro) ProcessUpdate(update WebsocketL2Update) error {
|
||||
return errors.New("coibasepro_websocket.go error - no data in websocket update")
|
||||
}
|
||||
|
||||
p := pair.NewCurrencyPairFromString(update.ProductID)
|
||||
p := currency.NewPairFromString(update.ProductID)
|
||||
|
||||
err := c.Websocket.Orderbook.Update(Bids, Asks, p, time.Now(), c.GetName(), "SPOT")
|
||||
if err != nil {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
|
||||
@@ -42,7 +42,14 @@ func (c *CoinbasePro) Run() {
|
||||
currencies = append(currencies, x.ID[0:3]+x.ID[4:])
|
||||
}
|
||||
}
|
||||
err = c.UpdateCurrencies(currencies, false, false)
|
||||
|
||||
var newCurrencies currency.Pairs
|
||||
for _, p := range currencies {
|
||||
newCurrencies = append(newCurrencies,
|
||||
currency.NewPairFromString(p))
|
||||
}
|
||||
|
||||
err = c.UpdateCurrencies(newCurrencies, false, false)
|
||||
if err != nil {
|
||||
log.Errorf("%s Failed to update available currencies.\n", c.GetName())
|
||||
}
|
||||
@@ -62,7 +69,7 @@ func (c *CoinbasePro) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
var currencies []exchange.AccountCurrencyInfo
|
||||
for i := 0; i < len(accountBalance); i++ {
|
||||
var exchangeCurrency exchange.AccountCurrencyInfo
|
||||
exchangeCurrency.CurrencyName = accountBalance[i].Currency
|
||||
exchangeCurrency.CurrencyName = currency.NewCode(accountBalance[i].Currency)
|
||||
exchangeCurrency.TotalValue = accountBalance[i].Available
|
||||
exchangeCurrency.Hold = accountBalance[i].Hold
|
||||
|
||||
@@ -77,7 +84,7 @@ func (c *CoinbasePro) GetAccountInfo() (exchange.AccountInfo, error) {
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (c *CoinbasePro) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (c *CoinbasePro) UpdateTicker(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
tick, err := c.GetTicker(exchange.FormatExchangeCurrency(c.Name, p).String())
|
||||
if err != nil {
|
||||
@@ -95,12 +102,17 @@ func (c *CoinbasePro) UpdateTicker(p pair.CurrencyPair, assetType string) (ticke
|
||||
tickerPrice.Last = tick.Price
|
||||
tickerPrice.High = stats.High
|
||||
tickerPrice.Low = stats.Low
|
||||
ticker.ProcessTicker(c.GetName(), p, tickerPrice, assetType)
|
||||
|
||||
err = ticker.ProcessTicker(c.GetName(), tickerPrice, assetType)
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
|
||||
return ticker.GetTicker(c.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetTickerPrice returns the ticker for a currency pair
|
||||
func (c *CoinbasePro) GetTickerPrice(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
func (c *CoinbasePro) GetTickerPrice(p currency.Pair, assetType string) (ticker.Price, error) {
|
||||
tickerNew, err := ticker.GetTicker(c.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return c.UpdateTicker(p, assetType)
|
||||
@@ -109,8 +121,8 @@ func (c *CoinbasePro) GetTickerPrice(p pair.CurrencyPair, assetType string) (tic
|
||||
}
|
||||
|
||||
// GetOrderbookEx returns orderbook base on the currency pair
|
||||
func (c *CoinbasePro) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.GetOrderbook(c.GetName(), p, assetType)
|
||||
func (c *CoinbasePro) GetOrderbookEx(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
ob, err := orderbook.Get(c.GetName(), p, assetType)
|
||||
if err != nil {
|
||||
return c.UpdateOrderbook(p, assetType)
|
||||
}
|
||||
@@ -118,7 +130,7 @@ func (c *CoinbasePro) GetOrderbookEx(p pair.CurrencyPair, assetType string) (ord
|
||||
}
|
||||
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (c *CoinbasePro) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
func (c *CoinbasePro) UpdateOrderbook(p currency.Pair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
orderbookNew, err := c.GetOrderbook(exchange.FormatExchangeCurrency(c.Name, p).String(), 2)
|
||||
if err != nil {
|
||||
@@ -135,8 +147,16 @@ func (c *CoinbasePro) UpdateOrderbook(p pair.CurrencyPair, assetType string) (or
|
||||
orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: obNew.Asks[x].Amount, Price: obNew.Asks[x].Price})
|
||||
}
|
||||
|
||||
orderbook.ProcessOrderbook(c.GetName(), p, orderBook, assetType)
|
||||
return orderbook.GetOrderbook(c.Name, p, assetType)
|
||||
orderBook.Pair = p
|
||||
orderBook.ExchangeName = c.GetName()
|
||||
orderBook.AssetType = assetType
|
||||
|
||||
err = orderBook.Process()
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
return orderbook.Get(c.Name, p, assetType)
|
||||
}
|
||||
|
||||
// GetFundingHistory returns funding history, deposits and
|
||||
@@ -147,23 +167,36 @@ func (c *CoinbasePro) GetFundingHistory() ([]exchange.FundHistory, error) {
|
||||
}
|
||||
|
||||
// GetExchangeHistory returns historic trade data since exchange opening.
|
||||
func (c *CoinbasePro) GetExchangeHistory(p pair.CurrencyPair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
func (c *CoinbasePro) GetExchangeHistory(p currency.Pair, assetType string) ([]exchange.TradeHistory, error) {
|
||||
var resp []exchange.TradeHistory
|
||||
|
||||
return resp, common.ErrNotYetImplemented
|
||||
}
|
||||
|
||||
// SubmitOrder submits a new order
|
||||
func (c *CoinbasePro) SubmitOrder(p pair.CurrencyPair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
func (c *CoinbasePro) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
var response string
|
||||
var err error
|
||||
|
||||
switch orderType {
|
||||
case exchange.MarketOrderType:
|
||||
response, err = c.PlaceMarginOrder("", amount, amount, side.ToString(), p.Pair().String(), "")
|
||||
response, err = c.PlaceMarginOrder("",
|
||||
amount,
|
||||
amount,
|
||||
side.ToString(),
|
||||
p.String(),
|
||||
"")
|
||||
case exchange.LimitOrderType:
|
||||
response, err = c.PlaceLimitOrder("", price, amount, side.ToString(), "", "", p.Pair().String(), "", false)
|
||||
response, err = c.PlaceLimitOrder("",
|
||||
price,
|
||||
amount,
|
||||
side.ToString(),
|
||||
"",
|
||||
"",
|
||||
p.String(),
|
||||
"",
|
||||
false)
|
||||
default:
|
||||
err = errors.New("order type not supported")
|
||||
}
|
||||
@@ -204,7 +237,7 @@ func (c *CoinbasePro) GetOrderInfo(orderID string) (exchange.OrderDetail, error)
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (c *CoinbasePro) GetDepositAddress(cryptocurrency pair.CurrencyItem, accountID string) (string, error) {
|
||||
func (c *CoinbasePro) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) {
|
||||
return "", common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
@@ -262,7 +295,8 @@ func (c *CoinbasePro) GetFeeByType(feeBuilder exchange.FeeBuilder) (float64, err
|
||||
func (c *CoinbasePro) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
|
||||
var respOrders []GeneralizedOrderResponse
|
||||
for _, currency := range getOrdersRequest.Currencies {
|
||||
resp, err := c.GetOrders([]string{"open", "pending", "active"}, exchange.FormatExchangeCurrency(c.Name, currency).String())
|
||||
resp, err := c.GetOrders([]string{"open", "pending", "active"},
|
||||
exchange.FormatExchangeCurrency(c.Name, currency).String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -271,7 +305,8 @@ func (c *CoinbasePro) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest
|
||||
|
||||
var orders []exchange.OrderDetail
|
||||
for _, order := range respOrders {
|
||||
currency := pair.NewCurrencyPairDelimiter(order.ProductID, c.ConfigCurrencyPairFormat.Delimiter)
|
||||
currency := currency.NewPairDelimiter(order.ProductID,
|
||||
c.ConfigCurrencyPairFormat.Delimiter)
|
||||
orderSide := exchange.OrderSide(strings.ToUpper(order.Side))
|
||||
orderType := exchange.OrderType(strings.ToUpper(order.Type))
|
||||
orderDate, err := time.Parse(time.RFC3339, order.CreatedAt)
|
||||
@@ -304,7 +339,8 @@ func (c *CoinbasePro) GetActiveOrders(getOrdersRequest exchange.GetOrdersRequest
|
||||
func (c *CoinbasePro) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest) ([]exchange.OrderDetail, error) {
|
||||
var respOrders []GeneralizedOrderResponse
|
||||
for _, currency := range getOrdersRequest.Currencies {
|
||||
resp, err := c.GetOrders([]string{"done", "settled"}, exchange.FormatExchangeCurrency(c.Name, currency).String())
|
||||
resp, err := c.GetOrders([]string{"done", "settled"},
|
||||
exchange.FormatExchangeCurrency(c.Name, currency).String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -313,7 +349,8 @@ func (c *CoinbasePro) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest
|
||||
|
||||
var orders []exchange.OrderDetail
|
||||
for _, order := range respOrders {
|
||||
currency := pair.NewCurrencyPairDelimiter(order.ProductID, c.ConfigCurrencyPairFormat.Delimiter)
|
||||
currency := currency.NewPairDelimiter(order.ProductID,
|
||||
c.ConfigCurrencyPairFormat.Delimiter)
|
||||
orderSide := exchange.OrderSide(strings.ToUpper(order.Side))
|
||||
orderType := exchange.OrderType(strings.ToUpper(order.Type))
|
||||
orderDate, err := time.Parse(time.RFC3339, order.CreatedAt)
|
||||
@@ -335,7 +372,8 @@ func (c *CoinbasePro) GetOrderHistory(getOrdersRequest exchange.GetOrdersRequest
|
||||
}
|
||||
|
||||
exchange.FilterOrdersByType(&orders, getOrdersRequest.OrderType)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks, getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersByTickRange(&orders, getOrdersRequest.StartTicks,
|
||||
getOrdersRequest.EndTicks)
|
||||
exchange.FilterOrdersBySide(&orders, getOrdersRequest.OrderSide)
|
||||
|
||||
return orders, nil
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user