mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-07 15:11:03 +00:00
poloniex: websocket update (#659)
* poloniex: websocket update with debug output and currency tracking system * linter: fix issues * nits: Addr * poloniex: govet fix * nits: addr * Bittrex: Fix fee test
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/thrasher-corp/gocryptotrader/common"
|
"github.com/thrasher-corp/gocryptotrader/common"
|
||||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||||
|
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
|
||||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||||
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
|
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
|
||||||
"github.com/thrasher-corp/gocryptotrader/exchanges/stats"
|
"github.com/thrasher-corp/gocryptotrader/exchanges/stats"
|
||||||
@@ -323,6 +324,11 @@ func (bot *Engine) WebsocketDataHandler(exchName string, data interface{}) error
|
|||||||
}
|
}
|
||||||
printOrderbookSummary(d, "websocket", bot, nil)
|
printOrderbookSummary(d, "websocket", bot, nil)
|
||||||
case *order.Detail:
|
case *order.Detail:
|
||||||
|
if bot.Settings.Verbose {
|
||||||
|
printOrderSummary(d)
|
||||||
|
}
|
||||||
|
// TODO: Dont check if exists this creates two locks, on conflict update
|
||||||
|
// else insert.
|
||||||
if !bot.OrderManager.orderStore.exists(d) {
|
if !bot.OrderManager.orderStore.exists(d) {
|
||||||
err := bot.OrderManager.orderStore.Add(d)
|
err := bot.OrderManager.orderStore.Add(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -335,9 +341,11 @@ func (bot *Engine) WebsocketDataHandler(exchName string, data interface{}) error
|
|||||||
}
|
}
|
||||||
od.UpdateOrderFromDetail(d)
|
od.UpdateOrderFromDetail(d)
|
||||||
}
|
}
|
||||||
case *order.Cancel:
|
|
||||||
return bot.OrderManager.Cancel(d)
|
|
||||||
case *order.Modify:
|
case *order.Modify:
|
||||||
|
if bot.Settings.Verbose {
|
||||||
|
printOrderChangeSummary(d)
|
||||||
|
}
|
||||||
|
// TODO: On conflict update or insert if not found
|
||||||
od, err := bot.OrderManager.orderStore.GetByExchangeAndID(d.Exchange, d.ID)
|
od, err := bot.OrderManager.orderStore.GetByExchangeAndID(d.Exchange, d.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -347,6 +355,10 @@ func (bot *Engine) WebsocketDataHandler(exchName string, data interface{}) error
|
|||||||
return errors.New(d.Error())
|
return errors.New(d.Error())
|
||||||
case stream.UnhandledMessageWarning:
|
case stream.UnhandledMessageWarning:
|
||||||
log.Warn(log.WebsocketMgr, d.Message)
|
log.Warn(log.WebsocketMgr, d.Message)
|
||||||
|
case account.Change:
|
||||||
|
if bot.Settings.Verbose {
|
||||||
|
printAccountHoldingsChangeSummary(d)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if bot.Settings.Verbose {
|
if bot.Settings.Verbose {
|
||||||
log.Warnf(log.WebsocketMgr,
|
log.Warnf(log.WebsocketMgr,
|
||||||
@@ -357,3 +369,59 @@ func (bot *Engine) WebsocketDataHandler(exchName string, data interface{}) error
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printOrderChangeSummary this function will be deprecated when a order manager
|
||||||
|
// update is done.
|
||||||
|
func printOrderChangeSummary(m *order.Modify) {
|
||||||
|
if m == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Debugf(log.WebsocketMgr,
|
||||||
|
"Order Change: %s %s %s %s %s %s OrderID:%s ClientOrderID:%s Price:%f Amount:%f Executed Amount:%f Remaining Amount:%f",
|
||||||
|
m.Exchange,
|
||||||
|
m.AssetType,
|
||||||
|
m.Pair,
|
||||||
|
m.Status,
|
||||||
|
m.Type,
|
||||||
|
m.Side,
|
||||||
|
m.ID,
|
||||||
|
m.ClientOrderID,
|
||||||
|
m.Price,
|
||||||
|
m.Amount,
|
||||||
|
m.ExecutedAmount,
|
||||||
|
m.RemainingAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
// printOrderSummary this function will be deprecated when a order manager
|
||||||
|
// update is done.
|
||||||
|
func printOrderSummary(m *order.Detail) {
|
||||||
|
if m == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Debugf(log.WebsocketMgr,
|
||||||
|
"New Order: %s %s %s %s %s %s OrderID:%s ClientOrderID:%s Price:%f Amount:%f Executed Amount:%f Remaining Amount:%f",
|
||||||
|
m.Exchange,
|
||||||
|
m.AssetType,
|
||||||
|
m.Pair,
|
||||||
|
m.Status,
|
||||||
|
m.Type,
|
||||||
|
m.Side,
|
||||||
|
m.ID,
|
||||||
|
m.ClientOrderID,
|
||||||
|
m.Price,
|
||||||
|
m.Amount,
|
||||||
|
m.ExecutedAmount,
|
||||||
|
m.RemainingAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
// printAccountHoldingsChangeSummary this function will be deprecated when a
|
||||||
|
// account holdings update is done.
|
||||||
|
func printAccountHoldingsChangeSummary(m account.Change) {
|
||||||
|
log.Debugf(log.WebsocketMgr,
|
||||||
|
"Account Holdings Balance Changed: %s %s %s has changed balance by %f for account: %s",
|
||||||
|
m.Exchange,
|
||||||
|
m.Asset,
|
||||||
|
m.Currency,
|
||||||
|
m.Amount,
|
||||||
|
m.Account)
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,3 +47,12 @@ type Balance struct {
|
|||||||
TotalValue float64
|
TotalValue float64
|
||||||
Hold float64
|
Hold float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Change defines incoming balance change on currency holdings
|
||||||
|
type Change struct {
|
||||||
|
Exchange string
|
||||||
|
Currency currency.Code
|
||||||
|
Asset asset.Item
|
||||||
|
Amount float64
|
||||||
|
Account string
|
||||||
|
}
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error {
|
|||||||
Err: err,
|
Err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.Websocket.DataHandler <- &order.Cancel{
|
b.Websocket.DataHandler <- &order.Modify{
|
||||||
Price: response.Data[x].Price,
|
Price: response.Data[x].Price,
|
||||||
Amount: response.Data[x].OrderQuantity,
|
Amount: response.Data[x].OrderQuantity,
|
||||||
Exchange: b.Name,
|
Exchange: b.Name,
|
||||||
|
|||||||
@@ -304,8 +304,8 @@ func TestGetFee(t *testing.T) {
|
|||||||
// CryptocurrencyWithdrawalFee Basic
|
// CryptocurrencyWithdrawalFee Basic
|
||||||
feeBuilder = setFeeBuilder()
|
feeBuilder = setFeeBuilder()
|
||||||
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
||||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.00015) || err != nil {
|
if resp, err := b.GetFee(feeBuilder); resp != float64(0.0003) || err != nil {
|
||||||
t.Errorf("Expected: %f, Received: %f", float64(0.00015), resp)
|
t.Errorf("Expected: %f, Received: %f", float64(0.0003), resp)
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ const (
|
|||||||
Open Status = "OPEN"
|
Open Status = "OPEN"
|
||||||
AutoDeleverage Status = "ADL"
|
AutoDeleverage Status = "ADL"
|
||||||
Closed Status = "CLOSED"
|
Closed Status = "CLOSED"
|
||||||
|
Pending Status = "PENDING"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Type enforces a standard for order types across the code base
|
// Type enforces a standard for order types across the code base
|
||||||
|
|||||||
235
exchanges/poloniex/currency_details.go
Normal file
235
exchanges/poloniex/currency_details.go
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
package poloniex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CurrencyDetails stores a map of currencies associated with their ID
|
||||||
|
type CurrencyDetails struct {
|
||||||
|
pairs map[float64]PairSummaryInfo
|
||||||
|
codes map[float64]CodeSummaryInfo
|
||||||
|
// Mutex used for future when we will periodically update this table every
|
||||||
|
// week or so in production
|
||||||
|
m sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// PairSummaryInfo defines currency pair information
|
||||||
|
type PairSummaryInfo struct {
|
||||||
|
Pair currency.Pair
|
||||||
|
IsFrozen bool
|
||||||
|
PostOnly bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// CodeSummaryInfo defines currency information
|
||||||
|
type CodeSummaryInfo struct {
|
||||||
|
Currency currency.Code
|
||||||
|
WithdrawalTXFee float64
|
||||||
|
MinimumConfirmations int64
|
||||||
|
DepositAddress string
|
||||||
|
WithdrawalDepositDisabled bool
|
||||||
|
Frozen bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
errCannotLoadNoData = errors.New("cannot load websocket currency data as data is nil")
|
||||||
|
errNoDepositAddress = errors.New("no public deposit address for currency")
|
||||||
|
errPairMapIsNil = errors.New("cannot get currency pair, map is nil")
|
||||||
|
errCodeMapIsNil = errors.New("cannot get currency code, map is nil")
|
||||||
|
errCurrencyNotFoundInMap = errors.New("currency not found")
|
||||||
|
)
|
||||||
|
|
||||||
|
// loadPairs loads currency pair associations with unique identifiers from
|
||||||
|
// ticker data map
|
||||||
|
func (w *CurrencyDetails) loadPairs(data map[string]Ticker) error {
|
||||||
|
if data == nil {
|
||||||
|
return errCannotLoadNoData
|
||||||
|
}
|
||||||
|
w.m.Lock()
|
||||||
|
defer w.m.Unlock()
|
||||||
|
for k, v := range data {
|
||||||
|
pair, err := currency.NewPairFromString(k)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if w.pairs == nil {
|
||||||
|
w.pairs = make(map[float64]PairSummaryInfo)
|
||||||
|
}
|
||||||
|
w.pairs[v.ID] = PairSummaryInfo{
|
||||||
|
Pair: pair,
|
||||||
|
IsFrozen: v.IsFrozen == 1,
|
||||||
|
PostOnly: v.PostOnly == 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadCodes loads currency codes from currency map
|
||||||
|
func (w *CurrencyDetails) loadCodes(data map[string]Currencies) error {
|
||||||
|
if data == nil {
|
||||||
|
return errCannotLoadNoData
|
||||||
|
}
|
||||||
|
w.m.Lock()
|
||||||
|
defer w.m.Unlock()
|
||||||
|
for k, v := range data {
|
||||||
|
if v.Delisted == 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if w.codes == nil {
|
||||||
|
w.codes = make(map[float64]CodeSummaryInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.codes[v.ID] = CodeSummaryInfo{
|
||||||
|
Currency: currency.NewCode(k),
|
||||||
|
WithdrawalTXFee: v.TxFee,
|
||||||
|
MinimumConfirmations: v.MinConfirmations,
|
||||||
|
DepositAddress: v.DepositAddress,
|
||||||
|
WithdrawalDepositDisabled: v.WithdrawalDepositDisabled == 1,
|
||||||
|
Frozen: v.Frozen == 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPair returns a currency pair by its ID
|
||||||
|
func (w *CurrencyDetails) GetPair(id float64) (currency.Pair, error) {
|
||||||
|
w.m.RLock()
|
||||||
|
defer w.m.RUnlock()
|
||||||
|
if w.pairs == nil {
|
||||||
|
return currency.Pair{}, errPairMapIsNil
|
||||||
|
}
|
||||||
|
|
||||||
|
p, ok := w.pairs[id]
|
||||||
|
if ok {
|
||||||
|
return p.Pair, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is here so we can still log an order with the ID as the currency
|
||||||
|
// pair which you can then cross reference later with the exchange ID list,
|
||||||
|
// rather than error out.
|
||||||
|
op, err := currency.NewPairFromString(strconv.FormatFloat(id, 'f', -1, 64))
|
||||||
|
if err != nil {
|
||||||
|
return op, err
|
||||||
|
}
|
||||||
|
return op, errIDNotFoundInPairMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCode returns a currency code by its ID
|
||||||
|
func (w *CurrencyDetails) GetCode(id float64) (currency.Code, error) {
|
||||||
|
w.m.RLock()
|
||||||
|
defer w.m.RUnlock()
|
||||||
|
if w.codes == nil {
|
||||||
|
return currency.Code{}, errCodeMapIsNil
|
||||||
|
}
|
||||||
|
c, ok := w.codes[id]
|
||||||
|
if ok {
|
||||||
|
return c.Currency, nil
|
||||||
|
}
|
||||||
|
return currency.Code{}, errIDNotFoundInCodeMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWithdrawalTXFee returns withdrawal transaction fee for the currency
|
||||||
|
func (w *CurrencyDetails) GetWithdrawalTXFee(c currency.Code) (float64, error) {
|
||||||
|
w.m.RLock()
|
||||||
|
defer w.m.RUnlock()
|
||||||
|
if w.codes == nil {
|
||||||
|
return 0, errCodeMapIsNil
|
||||||
|
}
|
||||||
|
for _, v := range w.codes {
|
||||||
|
if v.Currency == c {
|
||||||
|
return v.WithdrawalTXFee, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, errCurrencyNotFoundInMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDepositAddress returns the public deposit address details for the currency
|
||||||
|
func (w *CurrencyDetails) GetDepositAddress(c currency.Code) (string, error) {
|
||||||
|
w.m.RLock()
|
||||||
|
defer w.m.RUnlock()
|
||||||
|
if w.codes == nil {
|
||||||
|
return "", errCodeMapIsNil
|
||||||
|
}
|
||||||
|
for _, v := range w.codes {
|
||||||
|
if v.Currency == c {
|
||||||
|
if v.DepositAddress == "" {
|
||||||
|
return "", errNoDepositAddress
|
||||||
|
}
|
||||||
|
return v.DepositAddress, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", errCurrencyNotFoundInMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsWithdrawAndDepositsEnabled returns if withdrawals or deposits are enabled
|
||||||
|
func (w *CurrencyDetails) IsWithdrawAndDepositsEnabled(c currency.Code) (bool, error) {
|
||||||
|
w.m.RLock()
|
||||||
|
defer w.m.RUnlock()
|
||||||
|
if w.codes == nil {
|
||||||
|
return false, errCodeMapIsNil
|
||||||
|
}
|
||||||
|
for _, v := range w.codes {
|
||||||
|
if v.Currency == c {
|
||||||
|
return !v.WithdrawalDepositDisabled, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, errCurrencyNotFoundInMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTradingEnabledForCurrency returns if the currency is allowed to be traded
|
||||||
|
func (w *CurrencyDetails) IsTradingEnabledForCurrency(c currency.Code) (bool, error) {
|
||||||
|
w.m.RLock()
|
||||||
|
defer w.m.RUnlock()
|
||||||
|
if w.codes == nil {
|
||||||
|
return false, errCodeMapIsNil
|
||||||
|
}
|
||||||
|
for _, v := range w.codes {
|
||||||
|
if v.Currency == c {
|
||||||
|
return !v.Frozen, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, errCurrencyNotFoundInMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTradingEnabledForPair returns if the currency pair is allowed to be traded
|
||||||
|
func (w *CurrencyDetails) IsTradingEnabledForPair(pair currency.Pair) (bool, error) {
|
||||||
|
w.m.RLock()
|
||||||
|
defer w.m.RUnlock()
|
||||||
|
if w.codes == nil {
|
||||||
|
return false, errCodeMapIsNil
|
||||||
|
}
|
||||||
|
for _, v := range w.pairs {
|
||||||
|
if v.Pair.Equal(pair) {
|
||||||
|
return !v.IsFrozen, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, errCurrencyNotFoundInMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPostOnlyForPair returns if an order is allowed to take liquidity from the
|
||||||
|
// books or reduce positions
|
||||||
|
func (w *CurrencyDetails) IsPostOnlyForPair(pair currency.Pair) (bool, error) {
|
||||||
|
w.m.RLock()
|
||||||
|
defer w.m.RUnlock()
|
||||||
|
if w.codes == nil {
|
||||||
|
return false, errCodeMapIsNil
|
||||||
|
}
|
||||||
|
for _, v := range w.pairs {
|
||||||
|
if v.Pair.Equal(pair) {
|
||||||
|
return v.PostOnly, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, errCurrencyNotFoundInMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// isInitial checks state of maps to determine if they have been loaded or not
|
||||||
|
func (w *CurrencyDetails) isInitial() bool {
|
||||||
|
w.m.RLock()
|
||||||
|
defer w.m.RUnlock()
|
||||||
|
return w.codes == nil || w.pairs == nil
|
||||||
|
}
|
||||||
209
exchanges/poloniex/currency_details_test.go
Normal file
209
exchanges/poloniex/currency_details_test.go
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
package poloniex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWsCurrencyMap(t *testing.T) {
|
||||||
|
var m CurrencyDetails
|
||||||
|
|
||||||
|
if !m.isInitial() {
|
||||||
|
t.Fatal("unexpected value")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := m.loadPairs(nil)
|
||||||
|
if !errors.Is(err, errCannotLoadNoData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCannotLoadNoData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.loadCodes(nil)
|
||||||
|
if !errors.Is(err, errCannotLoadNoData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCannotLoadNoData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.GetPair(1337)
|
||||||
|
if !errors.Is(err, errPairMapIsNil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errPairMapIsNil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.GetCode(1337)
|
||||||
|
if !errors.Is(err, errCodeMapIsNil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCodeMapIsNil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.GetWithdrawalTXFee(currency.Code{})
|
||||||
|
if !errors.Is(err, errCodeMapIsNil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCodeMapIsNil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.GetDepositAddress(currency.Code{})
|
||||||
|
if !errors.Is(err, errCodeMapIsNil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCodeMapIsNil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.IsWithdrawAndDepositsEnabled(currency.Code{})
|
||||||
|
if !errors.Is(err, errCodeMapIsNil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCodeMapIsNil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.IsTradingEnabledForCurrency(currency.Code{})
|
||||||
|
if !errors.Is(err, errCodeMapIsNil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCodeMapIsNil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.IsTradingEnabledForPair(currency.Pair{})
|
||||||
|
if !errors.Is(err, errCodeMapIsNil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCodeMapIsNil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.IsPostOnlyForPair(currency.Pair{})
|
||||||
|
if !errors.Is(err, errCodeMapIsNil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCodeMapIsNil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := p.GetCurrencies()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.loadCodes(c)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tick, err := p.GetTicker()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.loadPairs(tick)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pTest, err := m.GetPair(1337)
|
||||||
|
if !errors.Is(err, errIDNotFoundInPairMap) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errIDNotFoundInPairMap, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pTest.String() != "1337" {
|
||||||
|
t.Fatal("unexpected value")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.GetCode(1337)
|
||||||
|
if !errors.Is(err, errIDNotFoundInCodeMap) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errIDNotFoundInCodeMap, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
btcusdt, err := m.GetPair(121)
|
||||||
|
if !errors.Is(err, nil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if btcusdt.String() != "USDT_BTC" {
|
||||||
|
t.Fatal("expecting USDT_BTC pair")
|
||||||
|
}
|
||||||
|
|
||||||
|
maid, err := m.GetCode(127)
|
||||||
|
if !errors.Is(err, nil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if maid.String() != "MAID" {
|
||||||
|
t.Fatal("unexpected value")
|
||||||
|
}
|
||||||
|
|
||||||
|
txFee, err := m.GetWithdrawalTXFee(maid)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if txFee != 80 {
|
||||||
|
t.Fatal("unexpected value")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.GetDepositAddress(maid)
|
||||||
|
if !errors.Is(err, errNoDepositAddress) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errNoDepositAddress, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dAddr, err := m.GetDepositAddress(currency.NewCode("BCN"))
|
||||||
|
if !errors.Is(err, nil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dAddr != "25cZNQYVAi3issDCoa6fWA2Aogd4FgPhYdpX3p8KLfhKC6sN8s6Q9WpcW4778TPwcUS5jEM25JrQvjD3XjsvXuNHSWhYUsu" {
|
||||||
|
t.Fatal("unexpected deposit address")
|
||||||
|
}
|
||||||
|
|
||||||
|
wdEnabled, err := m.IsWithdrawAndDepositsEnabled(maid)
|
||||||
|
if !errors.Is(err, nil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !wdEnabled {
|
||||||
|
t.Fatal("unexpected results")
|
||||||
|
}
|
||||||
|
|
||||||
|
tEnabled, err := m.IsTradingEnabledForCurrency(maid)
|
||||||
|
if !errors.Is(err, nil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tEnabled {
|
||||||
|
t.Fatal("unexpected results")
|
||||||
|
}
|
||||||
|
|
||||||
|
cp := currency.NewPair(currency.USDT, currency.BTC)
|
||||||
|
|
||||||
|
tEnabled, err = m.IsTradingEnabledForPair(cp)
|
||||||
|
if !errors.Is(err, nil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tEnabled {
|
||||||
|
t.Fatal("unexpected results")
|
||||||
|
}
|
||||||
|
|
||||||
|
postOnly, err := m.IsPostOnlyForPair(cp)
|
||||||
|
if !errors.Is(err, nil) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if postOnly {
|
||||||
|
t.Fatal("unexpected results")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.GetWithdrawalTXFee(currency.Code{})
|
||||||
|
if !errors.Is(err, errCurrencyNotFoundInMap) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCurrencyNotFoundInMap, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.GetDepositAddress(currency.Code{})
|
||||||
|
if !errors.Is(err, errCurrencyNotFoundInMap) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCurrencyNotFoundInMap, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.IsWithdrawAndDepositsEnabled(currency.Code{})
|
||||||
|
if !errors.Is(err, errCurrencyNotFoundInMap) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCurrencyNotFoundInMap, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.IsTradingEnabledForCurrency(currency.Code{})
|
||||||
|
if !errors.Is(err, errCurrencyNotFoundInMap) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCurrencyNotFoundInMap, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.IsTradingEnabledForPair(currency.Pair{})
|
||||||
|
if !errors.Is(err, errCurrencyNotFoundInMap) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCurrencyNotFoundInMap, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = m.IsPostOnlyForPair(currency.Pair{})
|
||||||
|
if !errors.Is(err, errCurrencyNotFoundInMap) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errCurrencyNotFoundInMap, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,6 +55,7 @@ const (
|
|||||||
// Poloniex is the overarching type across the poloniex package
|
// Poloniex is the overarching type across the poloniex package
|
||||||
type Poloniex struct {
|
type Poloniex struct {
|
||||||
exchange.Base
|
exchange.Base
|
||||||
|
details CurrencyDetails
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTicker returns current ticker information
|
// GetTicker returns current ticker information
|
||||||
@@ -258,27 +259,15 @@ func (p *Poloniex) GetBalances() (Balance, error) {
|
|||||||
|
|
||||||
// GetCompleteBalances returns complete balances from your account.
|
// GetCompleteBalances returns complete balances from your account.
|
||||||
func (p *Poloniex) GetCompleteBalances() (CompleteBalances, error) {
|
func (p *Poloniex) GetCompleteBalances() (CompleteBalances, error) {
|
||||||
var result interface{}
|
var result CompleteBalances
|
||||||
|
vals := url.Values{}
|
||||||
err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexBalancesComplete, url.Values{}, &result)
|
vals.Set("account", "all")
|
||||||
if err != nil {
|
err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot,
|
||||||
return CompleteBalances{}, err
|
http.MethodPost,
|
||||||
}
|
poloniexBalancesComplete,
|
||||||
|
vals,
|
||||||
data := result.(map[string]interface{})
|
&result)
|
||||||
balance := CompleteBalances{}
|
return result, err
|
||||||
balance.Currency = make(map[string]CompleteBalance)
|
|
||||||
|
|
||||||
for x, y := range data {
|
|
||||||
dataVals := y.(map[string]interface{})
|
|
||||||
balancesData := CompleteBalance{}
|
|
||||||
balancesData.Available, _ = strconv.ParseFloat(dataVals["available"].(string), 64)
|
|
||||||
balancesData.OnOrders, _ = strconv.ParseFloat(dataVals["onOrders"].(string), 64)
|
|
||||||
balancesData.BTCValue, _ = strconv.ParseFloat(dataVals["btcValue"].(string), 64)
|
|
||||||
balance.Currency[x] = balancesData
|
|
||||||
}
|
|
||||||
|
|
||||||
return balance, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDepositAddresses returns deposit addresses for all enabled cryptos.
|
// GetDepositAddresses returns deposit addresses for all enabled cryptos.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package poloniex
|
package poloniex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -565,7 +566,7 @@ func TestWsSubAck(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestWsTicker(t *testing.T) {
|
func TestWsTicker(t *testing.T) {
|
||||||
err := p.getCurrencyIDMap()
|
err := p.loadCurrencyDetails()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -577,7 +578,7 @@ func TestWsTicker(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestWsExchangeVolume(t *testing.T) {
|
func TestWsExchangeVolume(t *testing.T) {
|
||||||
err := p.getCurrencyIDMap()
|
err := p.loadCurrencyDetails()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -589,7 +590,8 @@ func TestWsExchangeVolume(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestWsTrades(t *testing.T) {
|
func TestWsTrades(t *testing.T) {
|
||||||
err := p.getCurrencyIDMap()
|
p.SetSaveTradeDataStatus(true)
|
||||||
|
err := p.loadCurrencyDetails()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -601,7 +603,7 @@ func TestWsTrades(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestWsPriceAggregateOrderbook(t *testing.T) {
|
func TestWsPriceAggregateOrderbook(t *testing.T) {
|
||||||
err := p.getCurrencyIDMap()
|
err := p.loadCurrencyDetails()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -617,25 +619,6 @@ func TestWsPriceAggregateOrderbook(t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func TestWsHandleAccountData(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
err := p.getCurrencyIDMap()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
jsons := []string{
|
|
||||||
`[1000,"",[["o",807230187,"0.00000000", "f"],["b",267,"e","0.10000000"]]]`,
|
|
||||||
`[1000,"",[["n",50,807230187,0,"1000.00000000","0.10000000","2018-11-07 16:42:42"],["b",267,"e","-0.10000000"]]]`,
|
|
||||||
`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345"]]]`,
|
|
||||||
`[1000,"",[["k", 1337, ""]]]`,
|
|
||||||
}
|
|
||||||
for i := range jsons {
|
|
||||||
err := p.wsHandleData([]byte(jsons[i]))
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetHistoricCandles(t *testing.T) {
|
func TestGetHistoricCandles(t *testing.T) {
|
||||||
currencyPair, err := currency.NewPairFromString("BTC_LTC")
|
currencyPair, err := currency.NewPairFromString("BTC_LTC")
|
||||||
@@ -712,3 +695,330 @@ func TestGetHistoricTrades(t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProcessAccountMarginPosition(t *testing.T) {
|
||||||
|
err := p.loadCurrencyDetails()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
margin := []byte(`[1000,"",[["m", 23432933, 28, "-0.06000000"]]]`)
|
||||||
|
err = p.wsHandleData(margin)
|
||||||
|
if !errors.Is(err, errNotEnoughData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errNotEnoughData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
margin = []byte(`[1000,"",[["m", "23432933", 28, "-0.06000000", null]]]`)
|
||||||
|
err = p.wsHandleData(margin)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
margin = []byte(`[1000,"",[["m", 23432933, "28", "-0.06000000", null]]]`)
|
||||||
|
err = p.wsHandleData(margin)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
margin = []byte(`[1000,"",[["m", 23432933, 28, -0.06000000, null]]]`)
|
||||||
|
err = p.wsHandleData(margin)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
margin = []byte(`[1000,"",[["m", 23432933, 28, "-0.06000000", null]]]`)
|
||||||
|
err = p.wsHandleData(margin)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProcessAccountPendingOrder(t *testing.T) {
|
||||||
|
err := p.loadCurrencyDetails()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pending := []byte(`[1000,"",[["p",431682155857,127,"1000.00000000","1.00000000","0"]]]`)
|
||||||
|
err = p.wsHandleData(pending)
|
||||||
|
if !errors.Is(err, errNotEnoughData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errNotEnoughData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pending = []byte(`[1000,"",[["p","431682155857",127,"1000.00000000","1.00000000","0",null]]]`)
|
||||||
|
err = p.wsHandleData(pending)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pending = []byte(`[1000,"",[["p",431682155857,"127","1000.00000000","1.00000000","0",null]]]`)
|
||||||
|
err = p.wsHandleData(pending)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pending = []byte(`[1000,"",[["p",431682155857,127,1000.00000000,"1.00000000","0",null]]]`)
|
||||||
|
err = p.wsHandleData(pending)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pending = []byte(`[1000,"",[["p",431682155857,127,"1000.00000000",1.00000000,"0",null]]]`)
|
||||||
|
err = p.wsHandleData(pending)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pending = []byte(`[1000,"",[["p",431682155857,127,"1000.00000000","1.00000000",0,null]]]`)
|
||||||
|
err = p.wsHandleData(pending)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pending = []byte(`[1000,"",[["p",431682155857,127,"1000.00000000","1.00000000","0",null]]]`)
|
||||||
|
err = p.wsHandleData(pending)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmatched pair in system
|
||||||
|
pending = []byte(`[1000,"",[["p",431682155857,666,"1000.00000000","1.00000000","0",null]]]`)
|
||||||
|
err = p.wsHandleData(pending)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProcessAccountOrderUpdate(t *testing.T) {
|
||||||
|
orderUpdate := []byte(`[1000,"",[["o",431682155857,"0.00000000","f"]]]`)
|
||||||
|
err := p.wsHandleData(orderUpdate)
|
||||||
|
if !errors.Is(err, errNotEnoughData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errNotEnoughData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderUpdate = []byte(`[1000,"",[["o","431682155857","0.00000000","f",null]]]`)
|
||||||
|
err = p.wsHandleData(orderUpdate)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderUpdate = []byte(`[1000,"",[["o",431682155857,0.00000000,"f",null]]]`)
|
||||||
|
err = p.wsHandleData(orderUpdate)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.00000000",123,null]]]`)
|
||||||
|
err = p.wsHandleData(orderUpdate)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.00000000","c",null]]]`)
|
||||||
|
err = p.wsHandleData(orderUpdate)
|
||||||
|
if !errors.Is(err, errNotEnoughData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errNotEnoughData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.50000000","c",null,"0.50000000"]]]`)
|
||||||
|
err = p.wsHandleData(orderUpdate)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.00000000","c",null,"1.00000000"]]]`)
|
||||||
|
err = p.wsHandleData(orderUpdate)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.50000000","f",null]]]`)
|
||||||
|
err = p.wsHandleData(orderUpdate)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderUpdate = []byte(`[1000,"",[["o",431682155857,"0.00000000","s",null]]]`)
|
||||||
|
err = p.wsHandleData(orderUpdate)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProcessAccountOrderLimit(t *testing.T) {
|
||||||
|
err := p.loadCurrencyDetails()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrade := []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000"]]]`)
|
||||||
|
err = p.wsHandleData(accountTrade)
|
||||||
|
if !errors.Is(err, errNotEnoughData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errNotEnoughData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrade = []byte(`[1000,"",[["n","127",431682155857,"0","1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`)
|
||||||
|
err = p.wsHandleData(accountTrade)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrade = []byte(`[1000,"",[["n",127,"431682155857","0","1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`)
|
||||||
|
err = p.wsHandleData(accountTrade)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrade = []byte(`[1000,"",[["n",127,431682155857,0,"1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`)
|
||||||
|
err = p.wsHandleData(accountTrade)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0",1000.00000000,"1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`)
|
||||||
|
err = p.wsHandleData(accountTrade)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000",1.00000000,"2021-04-13 07:19:56","1.00000000",null]]]`)
|
||||||
|
err = p.wsHandleData(accountTrade)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000","1.00000000",1234,"1.00000000",null]]]`)
|
||||||
|
err = p.wsHandleData(accountTrade)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000","1.00000000","2021-04-13 07:19:56",1.00000000,null]]]`)
|
||||||
|
err = p.wsHandleData(accountTrade)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrade = []byte(`[1000,"",[["n",127,431682155857,"0","1000.00000000","1.00000000","2021-04-13 07:19:56","1.00000000",null]]]`)
|
||||||
|
err = p.wsHandleData(accountTrade)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProcessAccountBalanceUpdate(t *testing.T) {
|
||||||
|
err := p.loadCurrencyDetails()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
balance := []byte(`[1000,"",[["b",243,"e"]]]`)
|
||||||
|
err = p.wsHandleData(balance)
|
||||||
|
if !errors.Is(err, errNotEnoughData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errNotEnoughData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
balance = []byte(`[1000,"",[["b","243","e","-1.00000000"]]]`)
|
||||||
|
err = p.wsHandleData(balance)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
balance = []byte(`[1000,"",[["b",243,1234,"-1.00000000"]]]`)
|
||||||
|
err = p.wsHandleData(balance)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
balance = []byte(`[1000,"",[["b",243,"e",-1.00000000]]]`)
|
||||||
|
err = p.wsHandleData(balance)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
balance = []byte(`[1000,"",[["b",243,"e","-1.00000000"]]]`)
|
||||||
|
err = p.wsHandleData(balance)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProcessAccountTrades(t *testing.T) {
|
||||||
|
accountTrades := []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345"]]]`)
|
||||||
|
err := p.wsHandleData(accountTrades)
|
||||||
|
if !errors.Is(err, errNotEnoughData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errNotEnoughData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrades = []byte(`[1000,"",[["t", "12345", "0.03000000", "0.50000000", "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345", "0.015"]]]`)
|
||||||
|
err = p.wsHandleData(accountTrades)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrades = []byte(`[1000,"",[["t", 12345, 0.03000000, "0.50000000", "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345", "0.015"]]]`)
|
||||||
|
err = p.wsHandleData(accountTrades)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", 0.50000000, "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345", "0.015"]]]`)
|
||||||
|
err = p.wsHandleData(accountTrades)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, 0.00000375, "2018-09-08 05:54:09", "12345", "0.015"]]]`)
|
||||||
|
err = p.wsHandleData(accountTrades)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, 0.0000037, "2018-09-08 05:54:09", "12345", "0.015"]]]`)
|
||||||
|
err = p.wsHandleData(accountTrades)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, "0.00000375", 12345, "12345", 0.015]]]`)
|
||||||
|
err = p.wsHandleData(accountTrades)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountTrades = []byte(`[1000,"",[["t", 12345, "0.03000000", "0.50000000", "0.00250000", 0, 6083059, "0.00000375", "2018-09-08 05:54:09", "12345", "0.015"]]]`)
|
||||||
|
err = p.wsHandleData(accountTrades)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProcessAccountKilledOrder(t *testing.T) {
|
||||||
|
kill := []byte(`[1000,"",[["k", 1337]]]`)
|
||||||
|
err := p.wsHandleData(kill)
|
||||||
|
if !errors.Is(err, errNotEnoughData) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errNotEnoughData, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
kill = []byte(`[1000,"",[["k", "1337", null]]]`)
|
||||||
|
err = p.wsHandleData(kill)
|
||||||
|
if !errors.Is(err, errTypeAssertionFailure) {
|
||||||
|
t.Fatalf("expected: %v but received: %v", errTypeAssertionFailure, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
kill = []byte(`[1000,"",[["k", 1337, null]]]`)
|
||||||
|
err = p.wsHandleData(kill)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetCompleteBalances(t *testing.T) {
|
||||||
|
if !mockTests && !areTestAPIKeysSet() {
|
||||||
|
t.Skip("API keys not set, mockTests false, skipping test")
|
||||||
|
}
|
||||||
|
_, err := p.GetCompleteBalances()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ type Ticker struct {
|
|||||||
PercentChange float64 `json:"percentChange,string"`
|
PercentChange float64 `json:"percentChange,string"`
|
||||||
BaseVolume float64 `json:"baseVolume,string"`
|
BaseVolume float64 `json:"baseVolume,string"`
|
||||||
QuoteVolume float64 `json:"quoteVolume,string"`
|
QuoteVolume float64 `json:"quoteVolume,string"`
|
||||||
IsFrozen int64 `json:"isFrozen,string"`
|
|
||||||
High24Hr float64 `json:"high24hr,string"`
|
High24Hr float64 `json:"high24hr,string"`
|
||||||
Low24Hr float64 `json:"low24hr,string"`
|
Low24Hr float64 `json:"low24hr,string"`
|
||||||
|
IsFrozen uint8 `json:"isFrozen,string"`
|
||||||
|
PostOnly uint8 `json:"postOnly,string"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrderbookResponseAll holds the full response type orderbook
|
// OrderbookResponseAll holds the full response type orderbook
|
||||||
@@ -27,9 +28,7 @@ type OrderbookResponseAll struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CompleteBalances holds the full balance data
|
// CompleteBalances holds the full balance data
|
||||||
type CompleteBalances struct {
|
type CompleteBalances map[string]CompleteBalance
|
||||||
Currency map[string]CompleteBalance
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrderbookResponse is a sub-type for orderbooks
|
// OrderbookResponse is a sub-type for orderbooks
|
||||||
type OrderbookResponse struct {
|
type OrderbookResponse struct {
|
||||||
@@ -116,15 +115,14 @@ type ChartData struct {
|
|||||||
|
|
||||||
// Currencies contains currency information
|
// Currencies contains currency information
|
||||||
type Currencies struct {
|
type Currencies struct {
|
||||||
ID float64 `json:"id"`
|
ID float64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
MaxDailyWithdrawal string `json:"maxDailyWithdrawal"`
|
TxFee float64 `json:"txFee,string"`
|
||||||
TxFee float64 `json:"txFee,string"`
|
MinConfirmations int64 `json:"minConf"`
|
||||||
MinConfirmations int64 `json:"minConf"`
|
DepositAddress string `json:"depositAddress"`
|
||||||
DepositAddresses interface{} `json:"depositAddress"`
|
WithdrawalDepositDisabled uint8 `json:"disabled"`
|
||||||
Disabled int64 `json:"disabled"`
|
Delisted uint8 `json:"delisted"`
|
||||||
Delisted int64 `json:"delisted"`
|
Frozen uint8 `json:"frozen"`
|
||||||
Frozen int64 `json:"frozen"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoanOrder holds loan order information
|
// LoanOrder holds loan order information
|
||||||
@@ -148,9 +146,9 @@ type Balance struct {
|
|||||||
|
|
||||||
// CompleteBalance contains the complete balance with a btcvalue
|
// CompleteBalance contains the complete balance with a btcvalue
|
||||||
type CompleteBalance struct {
|
type CompleteBalance struct {
|
||||||
Available float64
|
Available float64 `json:"available,string"`
|
||||||
OnOrders float64
|
OnOrders float64 `json:"onOrders,string"`
|
||||||
BTCValue float64
|
BTCValue float64 `json:"btcValue,string"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DepositAddresses holds the full address per crypto-currency
|
// DepositAddresses holds the full address per crypto-currency
|
||||||
@@ -442,13 +440,6 @@ var WithdrawalFees = map[currency.Code]float64{
|
|||||||
currency.ZEC: 0.001,
|
currency.ZEC: 0.001,
|
||||||
}
|
}
|
||||||
|
|
||||||
// WsAccountBalanceUpdateResponse Authenticated Ws Account data
|
|
||||||
type WsAccountBalanceUpdateResponse struct {
|
|
||||||
currencyID float64
|
|
||||||
wallet string
|
|
||||||
amount float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// WsOrderUpdateResponse Authenticated Ws Account data
|
// WsOrderUpdateResponse Authenticated Ws Account data
|
||||||
type WsOrderUpdateResponse struct {
|
type WsOrderUpdateResponse struct {
|
||||||
OrderNumber float64
|
OrderNumber float64
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
2426
testdata/http_mock/poloniex/poloniex.json
vendored
2426
testdata/http_mock/poloniex/poloniex.json
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user