asset: bitmask type optimisation (#922)

* asset: basic optim. bitmask

* glorious: nits

* currency: forgot parralel in testttttt

* ticker/orderbook: test fixes

* engine/rpcserver: fix and expand tests
This commit is contained in:
Ryan O'Hara-Reid
2022-04-28 09:49:43 +10:00
committed by GitHub
parent b45fbb80ec
commit b87a0791b0
41 changed files with 500 additions and 222 deletions

View File

@@ -525,19 +525,19 @@ func (bt *BackTest) setupExchangeSettings(cfg *config.Config) (exchange.Exchange
func (bt *BackTest) loadExchangePairAssetBase(exch, base, quote, ass string) (gctexchange.IBotExchange, currency.Pair, asset.Item, error) {
e, err := bt.exchangeManager.GetExchangeByName(exch)
if err != nil {
return nil, currency.EMPTYPAIR, "", err
return nil, currency.EMPTYPAIR, asset.Empty, err
}
var cp, fPair currency.Pair
cp, err = currency.NewPairFromStrings(base, quote)
if err != nil {
return nil, currency.EMPTYPAIR, "", err
return nil, currency.EMPTYPAIR, asset.Empty, err
}
var a asset.Item
a, err = asset.New(ass)
if err != nil {
return nil, currency.EMPTYPAIR, "", err
return nil, currency.EMPTYPAIR, asset.Empty, err
}
exchangeBase := e.GetBase()
@@ -547,7 +547,7 @@ func (bt *BackTest) loadExchangePairAssetBase(exch, base, quote, ass string) (gc
fPair, err = exchangeBase.FormatExchangeCurrency(cp, a)
if err != nil {
return nil, currency.EMPTYPAIR, "", err
return nil, currency.EMPTYPAIR, asset.Empty, err
}
return e, fPair, a, nil
}

View File

@@ -312,7 +312,7 @@ func applySlippageToPrice(direction gctorder.Side, price, slippageRate decimal.D
// SetExchangeAssetCurrencySettings sets the settings for an exchange, asset, currency
func (e *Exchange) SetExchangeAssetCurrencySettings(exch string, a asset.Item, cp currency.Pair, c *Settings) {
if c.Exchange == "" ||
c.Asset == "" ||
c.Asset == asset.Empty ||
c.Pair.IsEmpty() {
return
}

View File

@@ -44,7 +44,7 @@ func TestReset(t *testing.T) {
func TestSetCurrency(t *testing.T) {
t.Parallel()
e := Exchange{}
e.SetExchangeAssetCurrencySettings("", "", currency.EMPTYPAIR, &Settings{})
e.SetExchangeAssetCurrencySettings("", asset.Empty, currency.EMPTYPAIR, &Settings{})
if len(e.CurrencySettings) != 0 {
t.Error("expected 0")
}
@@ -265,7 +265,7 @@ func TestExecuteOrder(t *testing.T) {
Item: gctkline.Item{
Exchange: "",
Pair: currency.EMPTYPAIR,
Asset: "",
Asset: asset.Empty,
Interval: 0,
Candles: []gctkline.Candle{
{
@@ -386,7 +386,7 @@ func TestExecuteOrderBuySellSizeLimit(t *testing.T) {
Item: gctkline.Item{
Exchange: "",
Pair: currency.EMPTYPAIR,
Asset: "",
Asset: asset.Empty,
Interval: 0,
Candles: []gctkline.Candle{
{

View File

@@ -433,7 +433,7 @@ func (p *Portfolio) SetupCurrencySettingsMap(settings *exchange.Settings) (*Sett
if settings.Exchange == "" {
return nil, errExchangeUnset
}
if settings.Asset == "" {
if settings.Asset == asset.Empty {
return nil, errAssetUnset
}
if settings.Pair.IsEmpty() {

View File

@@ -303,7 +303,7 @@ func TestUpdate(t *testing.T) {
func TestGetFee(t *testing.T) {
t.Parallel()
p := Portfolio{}
f := p.GetFee("", "", currency.EMPTYPAIR)
f := p.GetFee("", asset.Empty, currency.EMPTYPAIR)
if !f.IsZero() {
t.Error("expected 0")
}
@@ -323,7 +323,7 @@ func TestGetFee(t *testing.T) {
func TestGetComplianceManager(t *testing.T) {
t.Parallel()
p := Portfolio{}
_, err := p.GetComplianceManager("", "", currency.EMPTYPAIR)
_, err := p.GetComplianceManager("", asset.Empty, currency.EMPTYPAIR)
if !errors.Is(err, errNoPortfolioSettings) {
t.Errorf("received: %v, expected: %v", err, errNoPortfolioSettings)
}

View File

@@ -852,18 +852,7 @@ func TestMatchesCurrency(t *testing.T) {
func TestCreateSnapshot(t *testing.T) {
f := FundManager{}
f.CreateSnapshot(time.Time{})
f.items = append(f.items, &Item{
exchange: "",
asset: "",
currency: currency.EMPTYCODE,
initialFunds: decimal.Decimal{},
available: decimal.Decimal{},
reserved: decimal.Decimal{},
transferFee: decimal.Decimal{},
pairedWith: nil,
usdTrackingCandles: nil,
snapshot: nil,
})
f.items = append(f.items, &Item{})
f.CreateSnapshot(time.Time{})
dfk := &kline.DataFromKline{

View File

@@ -535,7 +535,7 @@ func TestSupportsExchangeAssetType(t *testing.T) {
t.Error(err)
}
err = c.SupportsExchangeAssetType(testFakeExchangeName, "asdf")
err = c.SupportsExchangeAssetType(testFakeExchangeName, asset.Empty)
if err == nil {
t.Error("Expected error from invalid asset item")
}
@@ -988,7 +988,7 @@ func TestGetPairFormat(t *testing.T) {
asset.Spot: new(currency.PairStore),
},
}
_, err = c.GetPairFormat(testFakeExchangeName, asset.Item("invalid"))
_, err = c.GetPairFormat(testFakeExchangeName, asset.Empty)
if err == nil {
t.Error("Expected error from non-existent asset item")
}

View File

@@ -1,6 +1,7 @@
package currency
import (
"encoding/json"
"errors"
"fmt"
@@ -224,3 +225,33 @@ func (p *PairsManager) getPairStore(a asset.Item) (*PairStore, error) {
return c, nil
}
// UnmarshalJSON implements the unmarshal json interface so that the key can be
// correctly unmarshalled from a string into a uint.
func (fs *FullStore) UnmarshalJSON(d []byte) error {
var temp map[string]*PairStore
err := json.Unmarshal(d, &temp)
if err != nil {
return err
}
*fs = make(FullStore, len(temp))
for key, val := range temp {
ai, err := asset.New(key)
if err != nil {
return err
}
(*fs)[ai] = val
}
return nil
}
// MarshalJSON implements the marshal json interface so that the key can be
// correctly marshalled from a uint.
func (fs FullStore) MarshalJSON() ([]byte, error) {
temp := make(map[string]*PairStore, len(fs))
for key, val := range fs {
temp[key.String()] = val
}
return json.Marshal(temp)
}

View File

@@ -1,6 +1,8 @@
package currency
import (
"encoding/json"
"errors"
"testing"
"github.com/thrasher-corp/gocryptotrader/common/convert"
@@ -158,7 +160,7 @@ func TestGetPairs(t *testing.T) {
t.Fatal("pairs should be populated")
}
pairs, err = p.GetPairs("blah", true)
pairs, err = p.GetPairs(asset.Empty, true)
if err != nil {
t.Fatal(err)
}
@@ -361,3 +363,40 @@ func TestIsAssetEnabled_SetAssetEnabled(t *testing.T) {
t.Error("unexpected result")
}
}
func TestUnmarshalMarshal(t *testing.T) {
t.Parallel()
var um = make(FullStore)
um[asset.Spot] = &PairStore{AssetEnabled: convert.BoolPtr(true)}
data, err := json.Marshal(um)
if err != nil {
t.Fatal(err)
}
if string(data) != `{"spot":{"assetEnabled":true,"enabled":"","available":""}}` {
t.Fatal("unexpected value")
}
var another FullStore
err = json.Unmarshal(data, &another)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
if _, ok := another[asset.Spot]; !ok {
t.Fatal("expected values to be associated with spot")
}
data = []byte(`{123:{"assetEnabled":null,"enabled":"","available":""}}`)
err = json.Unmarshal(data, &another)
if errors.Is(err, nil) {
t.Fatalf("expected error")
}
data = []byte(`{"bro":{"assetEnabled":null,"enabled":"","available":""}}`)
err = json.Unmarshal(data, &another)
if !errors.Is(err, asset.ErrNotSupported) {
t.Fatalf("received: '%v' but expected: '%v'", err, asset.ErrNotSupported)
}
}

View File

@@ -8,15 +8,19 @@ import (
// PairsManager manages asset pairs
type PairsManager struct {
BypassConfigFormatUpgrades bool `json:"bypassConfigFormatUpgrades"`
RequestFormat *PairFormat `json:"requestFormat,omitempty"`
ConfigFormat *PairFormat `json:"configFormat,omitempty"`
UseGlobalFormat bool `json:"useGlobalFormat,omitempty"`
LastUpdated int64 `json:"lastUpdated,omitempty"`
Pairs map[asset.Item]*PairStore `json:"pairs"`
BypassConfigFormatUpgrades bool `json:"bypassConfigFormatUpgrades"`
RequestFormat *PairFormat `json:"requestFormat,omitempty"`
ConfigFormat *PairFormat `json:"configFormat,omitempty"`
UseGlobalFormat bool `json:"useGlobalFormat,omitempty"`
LastUpdated int64 `json:"lastUpdated,omitempty"`
Pairs FullStore `json:"pairs"`
m sync.RWMutex
}
// FullStore holds all supported asset types with the enabled and available
// pairs for an exchange.
type FullStore map[asset.Item]*PairStore
// PairStore stores a currency pair store
type PairStore struct {
AssetEnabled *bool `json:"assetEnabled"`

View File

@@ -240,7 +240,7 @@ func TestGetAllRPC(t *testing.T) {
func TestCanWithdrawRPC(t *testing.T) {
t.Parallel()
_, err := (*CurrencyStateManager)(nil).CanWithdrawRPC("", currency.EMPTYCODE, "")
_, err := (*CurrencyStateManager)(nil).CanWithdrawRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, ErrSubSystemNotStarted) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrSubSystemNotStarted)
}
@@ -248,7 +248,7 @@ func TestCanWithdrawRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{ErrorMeOne: true},
}).CanWithdrawRPC("", currency.EMPTYCODE, "")
}).CanWithdrawRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errManager) {
t.Fatalf("received: '%v' but expected: '%v'", err, errManager)
}
@@ -256,7 +256,7 @@ func TestCanWithdrawRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{ErrorMeTwo: true},
}).CanWithdrawRPC("", currency.EMPTYCODE, "")
}).CanWithdrawRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errExchange) {
t.Fatalf("received: '%v' but expected: '%v'", err, errExchange)
}
@@ -264,7 +264,7 @@ func TestCanWithdrawRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{},
}).CanWithdrawRPC("", currency.EMPTYCODE, "")
}).CanWithdrawRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
@@ -272,7 +272,7 @@ func TestCanWithdrawRPC(t *testing.T) {
func TestCanDepositRPC(t *testing.T) {
t.Parallel()
_, err := (*CurrencyStateManager)(nil).CanDepositRPC("", currency.EMPTYCODE, "")
_, err := (*CurrencyStateManager)(nil).CanDepositRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, ErrSubSystemNotStarted) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrSubSystemNotStarted)
}
@@ -280,7 +280,7 @@ func TestCanDepositRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{ErrorMeOne: true},
}).CanDepositRPC("", currency.EMPTYCODE, "")
}).CanDepositRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errManager) {
t.Fatalf("received: '%v' but expected: '%v'", err, errManager)
}
@@ -288,7 +288,7 @@ func TestCanDepositRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{ErrorMeTwo: true},
}).CanDepositRPC("", currency.EMPTYCODE, "")
}).CanDepositRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errExchange) {
t.Fatalf("received: '%v' but expected: '%v'", err, errExchange)
}
@@ -296,7 +296,7 @@ func TestCanDepositRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{},
}).CanDepositRPC("", currency.EMPTYCODE, "")
}).CanDepositRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
@@ -304,7 +304,7 @@ func TestCanDepositRPC(t *testing.T) {
func TestCanTradeRPC(t *testing.T) {
t.Parallel()
_, err := (*CurrencyStateManager)(nil).CanTradeRPC("", currency.EMPTYCODE, "")
_, err := (*CurrencyStateManager)(nil).CanTradeRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, ErrSubSystemNotStarted) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrSubSystemNotStarted)
}
@@ -312,7 +312,7 @@ func TestCanTradeRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{ErrorMeOne: true},
}).CanTradeRPC("", currency.EMPTYCODE, "")
}).CanTradeRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errManager) {
t.Fatalf("received: '%v' but expected: '%v'", err, errManager)
}
@@ -320,7 +320,7 @@ func TestCanTradeRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{ErrorMeTwo: true},
}).CanTradeRPC("", currency.EMPTYCODE, "")
}).CanTradeRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errExchange) {
t.Fatalf("received: '%v' but expected: '%v'", err, errExchange)
}
@@ -328,7 +328,7 @@ func TestCanTradeRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{},
}).CanTradeRPC("", currency.EMPTYCODE, "")
}).CanTradeRPC("", currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}
@@ -336,7 +336,7 @@ func TestCanTradeRPC(t *testing.T) {
func TestCanTradePairRPC(t *testing.T) {
t.Parallel()
_, err := (*CurrencyStateManager)(nil).CanTradePairRPC("", currency.EMPTYPAIR, "")
_, err := (*CurrencyStateManager)(nil).CanTradePairRPC("", currency.EMPTYPAIR, asset.Empty)
if !errors.Is(err, ErrSubSystemNotStarted) {
t.Fatalf("received: '%v' but expected: '%v'", err, ErrSubSystemNotStarted)
}
@@ -344,7 +344,7 @@ func TestCanTradePairRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{ErrorMeOne: true},
}).CanTradePairRPC("", currency.EMPTYPAIR, "")
}).CanTradePairRPC("", currency.EMPTYPAIR, asset.Empty)
if !errors.Is(err, errManager) {
t.Fatalf("received: '%v' but expected: '%v'", err, errManager)
}
@@ -352,7 +352,7 @@ func TestCanTradePairRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{ErrorMeTwo: true},
}).CanTradePairRPC("", currency.EMPTYPAIR, "")
}).CanTradePairRPC("", currency.EMPTYPAIR, asset.Empty)
if !errors.Is(err, errExchange) {
t.Fatalf("received: '%v' but expected: '%v'", err, errExchange)
}
@@ -360,7 +360,7 @@ func TestCanTradePairRPC(t *testing.T) {
_, err = (&CurrencyStateManager{
started: 1,
iExchangeManager: &fakeExchangeManagerino{},
}).CanTradePairRPC("", currency.EMPTYPAIR, "")
}).CanTradePairRPC("", currency.EMPTYPAIR, asset.Empty)
if !errors.Is(err, nil) {
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
}

View File

@@ -1479,11 +1479,17 @@ func (m *DataHistoryManager) convertDBModelToJob(dbModel *datahistoryjob.DataHis
return nil, fmt.Errorf("job %s could not convert database job: %w", dbModel.Nickname, err)
}
ai, err := asset.New(dbModel.Asset)
if err != nil {
return nil, fmt.Errorf("job %s could not derive asset: %w",
dbModel.Nickname, err)
}
resp := &DataHistoryJob{
ID: id,
Nickname: dbModel.Nickname,
Exchange: dbModel.ExchangeName,
Asset: asset.Item(dbModel.Asset),
Asset: ai,
Pair: cp,
StartDate: dbModel.StartDate,
EndDate: dbModel.EndDate,

View File

@@ -1498,11 +1498,15 @@ func dataHistoryTraderLoader(exch, a, base, quote string, start, _ time.Time) ([
if err != nil {
return nil, err
}
ai, err := asset.New(a)
if err != nil {
return nil, err
}
return []trade.Data{
{
Exchange: exch,
CurrencyPair: cp,
AssetType: asset.Item(a),
AssetType: ai,
Side: order.Buy,
Price: 1337,
Amount: 1337,

View File

@@ -520,14 +520,14 @@ func TestCancelOrder(t *testing.T) {
func TestGetOrderInfo(t *testing.T) {
m := OrdersSetup(t)
_, err := m.GetOrderInfo(context.Background(), "", "", currency.EMPTYPAIR, "")
_, err := m.GetOrderInfo(context.Background(), "", "", currency.EMPTYPAIR, asset.Empty)
if err == nil {
t.Error("Expected error due to empty order")
}
var result order.Detail
result, err = m.GetOrderInfo(context.Background(),
testExchange, "1337", currency.EMPTYPAIR, "")
testExchange, "1337", currency.EMPTYPAIR, asset.Empty)
if err != nil {
t.Error(err)
}
@@ -536,7 +536,7 @@ func TestGetOrderInfo(t *testing.T) {
}
result, err = m.GetOrderInfo(context.Background(),
testExchange, "1337", currency.EMPTYPAIR, "")
testExchange, "1337", currency.EMPTYPAIR, asset.Empty)
if err != nil {
t.Error(err)
}

View File

@@ -3547,8 +3547,9 @@ func (s *RPCServer) GetRecentTrades(ctx context.Context, r *gctrpc.GetSavedTrade
if err != nil {
return nil, err
}
var trades []trade.Data
trades, err = exch.GetRecentTrades(ctx, cp, asset.Item(r.AssetType))
trades, err = exch.GetRecentTrades(ctx, cp, a)
if err != nil {
return nil, err
}
@@ -4089,24 +4090,36 @@ func (s *RPCServer) CurrencyStateGetAll(_ context.Context, r *gctrpc.CurrencySta
// CurrencyStateWithdraw determines via RPC if the currency code is operational for
// withdrawal from an exchange
func (s *RPCServer) CurrencyStateWithdraw(_ context.Context, r *gctrpc.CurrencyStateWithdrawRequest) (*gctrpc.GenericResponse, error) {
ai, err := asset.New(r.Asset)
if err != nil {
return nil, err
}
return s.currencyStateManager.CanWithdrawRPC(r.Exchange,
currency.NewCode(r.Code),
asset.Item(r.Asset))
ai)
}
// CurrencyStateDeposit determines via RPC if the currency code is operational for
// depositing to an exchange
func (s *RPCServer) CurrencyStateDeposit(_ context.Context, r *gctrpc.CurrencyStateDepositRequest) (*gctrpc.GenericResponse, error) {
ai, err := asset.New(r.Asset)
if err != nil {
return nil, err
}
return s.currencyStateManager.CanDepositRPC(r.Exchange,
currency.NewCode(r.Code),
asset.Item(r.Asset))
ai)
}
// CurrencyStateTrading determines via RPC if the currency code is operational for trading
func (s *RPCServer) CurrencyStateTrading(_ context.Context, r *gctrpc.CurrencyStateTradingRequest) (*gctrpc.GenericResponse, error) {
ai, err := asset.New(r.Asset)
if err != nil {
return nil, err
}
return s.currencyStateManager.CanTradeRPC(r.Exchange,
currency.NewCode(r.Code),
asset.Item(r.Asset))
ai)
}
// CurrencyStateTradingPair determines via RPC if the pair is operational for trading
@@ -4121,19 +4134,23 @@ func (s *RPCServer) CurrencyStateTradingPair(_ context.Context, r *gctrpc.Curren
return nil, err
}
a := asset.Item(r.Asset)
err = checkParams(r.Exchange, exch, a, cp)
ai, err := asset.New(r.Asset)
if err != nil {
return nil, err
}
err = exch.CanTradePair(cp, a)
err = checkParams(r.Exchange, exch, ai, cp)
if err != nil {
return nil, err
}
err = exch.CanTradePair(cp, ai)
if err != nil {
return nil, err
}
return s.currencyStateManager.CanTradePairRPC(r.Exchange,
cp,
asset.Item(r.Asset))
ai)
}
// GetFuturesPositions returns pnl positions for an exchange asset pair
@@ -4147,13 +4164,17 @@ func (s *RPCServer) GetFuturesPositions(ctx context.Context, r *gctrpc.GetFuture
return nil, err
}
a := asset.Item(r.Asset)
err = checkParams(r.Exchange, exch, a, cp)
ai, err := asset.New(r.Asset)
if err != nil {
return nil, err
}
if !a.IsFutures() {
return nil, fmt.Errorf("%s %w", a, order.ErrNotFuturesAsset)
err = checkParams(r.Exchange, exch, ai, cp)
if err != nil {
return nil, err
}
if !ai.IsFutures() {
return nil, fmt.Errorf("%s %w", ai, order.ErrNotFuturesAsset)
}
var start, end time.Time
if r.StartDate != "" {
@@ -4182,7 +4203,7 @@ func (s *RPCServer) GetFuturesPositions(ctx context.Context, r *gctrpc.GetFuture
if creds.SubAccount != "" {
subErr = "for subaccount: " + creds.SubAccount
}
orders, err := exch.GetFuturesPositions(ctx, a, cp, start, end)
orders, err := exch.GetFuturesPositions(ctx, ai, cp, start, end)
if err != nil {
return nil, fmt.Errorf("%w %v", err, subErr)
}
@@ -4190,7 +4211,7 @@ func (s *RPCServer) GetFuturesPositions(ctx context.Context, r *gctrpc.GetFuture
return orders[i].Date.Before(orders[j].Date)
})
if r.Overwrite {
err = s.OrderManager.ClearFuturesTracking(r.Exchange, a, cp)
err = s.OrderManager.ClearFuturesTracking(r.Exchange, ai, cp)
if err != nil {
return nil, fmt.Errorf("%w %v", err, subErr)
}
@@ -4203,7 +4224,7 @@ func (s *RPCServer) GetFuturesPositions(ctx context.Context, r *gctrpc.GetFuture
}
}
}
pos, err := s.OrderManager.GetFuturesPositionsForExchange(r.Exchange, a, cp)
pos, err := s.OrderManager.GetFuturesPositionsForExchange(r.Exchange, ai, cp)
if err != nil {
return nil, fmt.Errorf("%w %v", err, subErr)
}
@@ -4314,7 +4335,11 @@ func (s *RPCServer) GetCollateral(ctx context.Context, r *gctrpc.GetCollateralRe
return nil, err
}
a := asset.Item(r.Asset)
a, err := asset.New(r.Asset)
if err != nil {
return nil, err
}
err = checkParams(r.Exchange, exch, a, currency.Pair{})
if err != nil {
return nil, err

View File

@@ -2002,7 +2002,16 @@ func TestCurrencyStateWithdraw(t *testing.T) {
Engine: &Engine{},
}).CurrencyStateWithdraw(context.Background(),
&gctrpc.CurrencyStateWithdrawRequest{
Exchange: "wow"})
Exchange: "wow", Asset: "meow"})
if !errors.Is(err, asset.ErrNotSupported) {
t.Fatalf("received: %v, but expected: %v", err, asset.ErrNotSupported)
}
_, err = (&RPCServer{
Engine: &Engine{},
}).CurrencyStateWithdraw(context.Background(),
&gctrpc.CurrencyStateWithdrawRequest{
Exchange: "wow", Asset: "spot"})
if !errors.Is(err, ErrSubSystemNotStarted) {
t.Fatalf("received: %v, but expected: %v", err, ErrSubSystemNotStarted)
}
@@ -2013,7 +2022,15 @@ func TestCurrencyStateDeposit(t *testing.T) {
_, err := (&RPCServer{
Engine: &Engine{},
}).CurrencyStateDeposit(context.Background(),
&gctrpc.CurrencyStateDepositRequest{Exchange: "wow"})
&gctrpc.CurrencyStateDepositRequest{Exchange: "wow", Asset: "meow"})
if !errors.Is(err, asset.ErrNotSupported) {
t.Fatalf("received: %v, but expected: %v", err, asset.ErrNotSupported)
}
_, err = (&RPCServer{
Engine: &Engine{},
}).CurrencyStateDeposit(context.Background(),
&gctrpc.CurrencyStateDepositRequest{Exchange: "wow", Asset: "spot"})
if !errors.Is(err, ErrSubSystemNotStarted) {
t.Fatalf("received: %v, but expected: %v", err, ErrSubSystemNotStarted)
}
@@ -2024,7 +2041,15 @@ func TestCurrencyStateTrading(t *testing.T) {
_, err := (&RPCServer{
Engine: &Engine{},
}).CurrencyStateTrading(context.Background(),
&gctrpc.CurrencyStateTradingRequest{Exchange: "wow"})
&gctrpc.CurrencyStateTradingRequest{Exchange: "wow", Asset: "meow"})
if !errors.Is(err, asset.ErrNotSupported) {
t.Fatalf("received: %v, but expected: %v", err, asset.ErrNotSupported)
}
_, err = (&RPCServer{
Engine: &Engine{},
}).CurrencyStateTrading(context.Background(),
&gctrpc.CurrencyStateTradingRequest{Exchange: "wow", Asset: "spot"})
if !errors.Is(err, ErrSubSystemNotStarted) {
t.Fatalf("received: %v, but expected: %v", err, ErrSubSystemNotStarted)
}

View File

@@ -103,7 +103,7 @@ func TestHoldings(t *testing.T) {
t.Error("error cannot be nil")
}
_, err = GetHoldings("bla", asset.Item("hi"))
_, err = GetHoldings("bla", asset.Empty)
if err == nil {
t.Error("error cannot be nil since an invalid asset type is provided")
}

View File

@@ -1,6 +1,7 @@
package asset
import (
"encoding/json"
"errors"
"fmt"
"strings"
@@ -8,54 +9,87 @@ import (
var (
// ErrNotSupported is an error for an unsupported asset type
ErrNotSupported = errors.New("received unsupported asset type")
ErrNotSupported = errors.New("unsupported asset type")
)
// Item stores the asset type
type Item string
type Item uint16
// Items stores a list of assets types
type Items []Item
// Const vars for asset package
const (
Spot = Item("spot")
Margin = Item("margin")
MarginFunding = Item("marginfunding")
Index = Item("index")
Binary = Item("binary")
PerpetualContract = Item("perpetualcontract")
PerpetualSwap = Item("perpetualswap")
Futures = Item("futures")
UpsideProfitContract = Item("upsideprofitcontract")
DownsideProfitContract = Item("downsideprofitcontract")
CoinMarginedFutures = Item("coinmarginedfutures")
USDTMarginedFutures = Item("usdtmarginedfutures")
Empty Item = 0
Spot Item = 1 << iota
Margin
MarginFunding
Index
Binary
PerpetualContract
PerpetualSwap
Futures
UpsideProfitContract
DownsideProfitContract
CoinMarginedFutures
USDTMarginedFutures
futuresFlag = PerpetualContract | PerpetualSwap | Futures | UpsideProfitContract | DownsideProfitContract | CoinMarginedFutures | USDTMarginedFutures
supportedFlag = Spot | Margin | MarginFunding | Index | Binary | PerpetualContract | PerpetualSwap | Futures | UpsideProfitContract | DownsideProfitContract | CoinMarginedFutures | USDTMarginedFutures
spot = "spot"
margin = "margin"
marginFunding = "marginfunding"
index = "index"
binary = "binary"
perpetualContract = "perpetualcontract"
perpetualSwap = "perpetualswap"
futures = "futures"
upsideProfitContract = "upsideprofitcontract"
downsideProfitContract = "downsideprofitcontract"
coinMarginedFutures = "coinmarginedfutures"
usdtMarginedFutures = "usdtmarginedfutures"
)
var supported = Items{
Spot,
Margin,
MarginFunding,
Index,
Binary,
PerpetualContract,
PerpetualSwap,
Futures,
UpsideProfitContract,
DownsideProfitContract,
CoinMarginedFutures,
USDTMarginedFutures,
}
var (
supportedList = Items{Spot, Margin, MarginFunding, Index, Binary, PerpetualContract, PerpetualSwap, Futures, UpsideProfitContract, DownsideProfitContract, CoinMarginedFutures, USDTMarginedFutures}
)
// Supported returns a list of supported asset types
func Supported() Items {
return supported
return supportedList
}
// returns an Item to string
func (a Item) String() string {
return string(a)
switch a {
case Spot:
return spot
case Margin:
return margin
case MarginFunding:
return marginFunding
case Index:
return index
case Binary:
return binary
case PerpetualContract:
return perpetualContract
case PerpetualSwap:
return perpetualSwap
case Futures:
return futures
case UpsideProfitContract:
return upsideProfitContract
case DownsideProfitContract:
return downsideProfitContract
case CoinMarginedFutures:
return coinMarginedFutures
case USDTMarginedFutures:
return usdtMarginedFutures
default:
return ""
}
}
// Strings converts an asset type array to a string array
@@ -70,13 +104,11 @@ func (a Items) Strings() []string {
// Contains returns whether or not the supplied asset exists
// in the list of Items
func (a Items) Contains(i Item) bool {
if !i.IsValid() {
return false
}
for x := range a {
if a[x].String() == i.String() {
return true
if i.IsValid() {
for x := range a {
if a[x] == i {
return true
}
}
}
return false
@@ -91,26 +123,69 @@ func (a Items) JoinToString(separator string) string {
// IsValid returns whether or not the supplied asset type is valid or
// not
func (a Item) IsValid() bool {
for x := range supported {
if supported[x].String() == a.String() {
return true
}
return a != Empty && supportedFlag&a == a
}
// UnmarshalJSON comforms type to the umarshaler interface
func (a *Item) UnmarshalJSON(d []byte) error {
var assetString string
err := json.Unmarshal(d, &assetString)
if err != nil {
return err
}
return false
if assetString == "" {
return nil
}
ai, err := New(assetString)
if err != nil {
return err
}
*a = ai
return nil
}
// MarshalJSON comforms type to the marshaller interface
func (a Item) MarshalJSON() ([]byte, error) {
return json.Marshal(a.String())
}
// New takes an input matches to relevant package assets
func New(input string) (Item, error) {
input = strings.ToLower(input)
for i := range supported {
if string(supported[i]) == input {
return supported[i], nil
}
switch input {
case spot:
return Spot, nil
case margin:
return Margin, nil
case marginFunding:
return MarginFunding, nil
case index:
return Index, nil
case binary:
return Binary, nil
case perpetualContract:
return PerpetualContract, nil
case perpetualSwap:
return PerpetualSwap, nil
case futures:
return Futures, nil
case upsideProfitContract:
return UpsideProfitContract, nil
case downsideProfitContract:
return DownsideProfitContract, nil
case coinMarginedFutures:
return CoinMarginedFutures, nil
case usdtMarginedFutures:
return USDTMarginedFutures, nil
default:
return 0, fmt.Errorf("%w '%v', only supports %s",
ErrNotSupported,
input,
supportedList)
}
return "", fmt.Errorf("%w %v, only supports %v",
ErrNotSupported,
input,
supported)
}
// UseDefault returns default asset type
@@ -120,10 +195,5 @@ func UseDefault() Item {
// IsFutures checks if the asset type is a futures contract based asset
func (a Item) IsFutures() bool {
switch a {
case PerpetualContract, PerpetualSwap, Futures, UpsideProfitContract,
DownsideProfitContract, CoinMarginedFutures, USDTMarginedFutures:
return true
}
return false
return a != Empty && futuresFlag&a == a
}

View File

@@ -1,19 +1,28 @@
package asset
import (
"encoding/json"
"errors"
"testing"
"github.com/thrasher-corp/gocryptotrader/common"
)
func TestString(t *testing.T) {
t.Parallel()
a := Spot
if a.String() != "spot" {
t.Fatal("TestString returned an unexpected result")
}
a = 0
if a.String() != "" {
t.Fatal("TestString returned an unexpected result")
}
}
func TestToStringArray(t *testing.T) {
t.Parallel()
a := Items{Spot, Futures}
result := a.Strings()
for x := range a {
@@ -24,8 +33,9 @@ func TestToStringArray(t *testing.T) {
}
func TestContains(t *testing.T) {
t.Parallel()
a := Items{Spot, Futures}
if a.Contains("meow") {
if a.Contains(666) {
t.Fatal("TestContains returned an unexpected result")
}
@@ -39,12 +49,13 @@ func TestContains(t *testing.T) {
// Every asset should be created and matched with func New so this should
// not be matched against list
if a.Contains("SpOt") {
if a.Contains(0) {
t.Error("TestContains returned an unexpected result")
}
}
func TestJoinToString(t *testing.T) {
t.Parallel()
a := Items{Spot, Futures}
if a.JoinToString(",") != "spot,futures" {
t.Fatal("TestJoinToString returned an unexpected result")
@@ -52,7 +63,8 @@ func TestJoinToString(t *testing.T) {
}
func TestIsValid(t *testing.T) {
if Item("rawr").IsValid() {
t.Parallel()
if Item(0).IsValid() {
t.Fatal("TestIsValid returned an unexpected result")
}
@@ -62,27 +74,49 @@ func TestIsValid(t *testing.T) {
}
func TestNew(t *testing.T) {
if _, err := New("Spota"); err == nil {
t.Fatal("TestNew returned an unexpected result")
t.Parallel()
cases := []struct {
Input string
Expected Item
Error error
}{
{Input: "Spota", Error: ErrNotSupported},
{Input: "MARGIN", Expected: Margin},
{Input: "MARGINFUNDING", Expected: MarginFunding},
{Input: "INDEX", Expected: Index},
{Input: "BINARY", Expected: Binary},
{Input: "PERPETUALCONTRACT", Expected: PerpetualContract},
{Input: "PERPETUALSWAP", Expected: PerpetualSwap},
{Input: "FUTURES", Expected: Futures},
{Input: "UpsideProfitContract", Expected: UpsideProfitContract},
{Input: "DownsideProfitContract", Expected: DownsideProfitContract},
{Input: "CoinMarginedFutures", Expected: CoinMarginedFutures},
{Input: "USDTMarginedFutures", Expected: USDTMarginedFutures},
}
a, err := New("SpOt")
if err != nil {
t.Fatal("TestNew returned an unexpected result", err)
}
if a != Spot {
t.Fatal("TestNew returned an unexpected result")
for x := range cases {
tt := cases[x]
t.Run("", func(t *testing.T) {
t.Parallel()
returned, err := New(tt.Input)
if !errors.Is(err, tt.Error) {
t.Fatalf("receieved: '%v' but expected: '%v'", err, tt.Error)
}
if returned != tt.Expected {
t.Fatalf("receieved: '%v' but expected: '%v'", returned, tt.Expected)
}
})
}
}
func TestSupported(t *testing.T) {
t.Parallel()
s := Supported()
if len(supported) != len(s) {
if len(supportedList) != len(s) {
t.Fatal("TestSupported mismatched lengths")
}
for i := 0; i < len(supported); i++ {
if s[i] != supported[i] {
for i := 0; i < len(supportedList); i++ {
if s[i] != supportedList[i] {
t.Fatal("TestSupported returned an unexpected result")
}
}
@@ -154,3 +188,57 @@ func TestIsFutures(t *testing.T) {
})
}
}
func TestUnmarshalMarshal(t *testing.T) {
t.Parallel()
data, err := json.Marshal(Item(0))
if !errors.Is(err, nil) {
t.Fatalf("receieved: '%v' but expected: '%v'", err, nil)
}
if string(data) != `""` {
t.Fatal("unexpected value")
}
data, err = json.Marshal(Spot)
if !errors.Is(err, nil) {
t.Fatalf("receieved: '%v' but expected: '%v'", err, nil)
}
if string(data) != `"spot"` {
t.Fatal("unexpected value")
}
var spot Item
err = json.Unmarshal(data, &spot)
if !errors.Is(err, nil) {
t.Fatalf("receieved: '%v' but expected: '%v'", err, nil)
}
if spot != Spot {
t.Fatal("unexpected value")
}
err = json.Unmarshal([]byte(`"confused"`), &spot)
if !errors.Is(err, ErrNotSupported) {
t.Fatalf("receieved: '%v' but expected: '%v'", err, ErrNotSupported)
}
err = json.Unmarshal([]byte(`""`), &spot)
if !errors.Is(err, nil) {
t.Fatalf("receieved: '%v' but expected: '%v'", err, nil)
}
err = json.Unmarshal([]byte(`123`), &spot)
if errors.Is(err, nil) {
t.Fatalf("receieved: '%v' but expected: '%v'", nil, "an error")
}
}
func TestUseDefault(t *testing.T) {
t.Parallel()
if UseDefault() != Spot {
t.Fatalf("receieved: '%v' but expected: '%v'", UseDefault(), Spot)
}
}

View File

@@ -666,7 +666,7 @@ func TestGetHistoricTrades(t *testing.T) {
func TestUpdateOrderExecutionLimits(t *testing.T) {
t.Parallel()
err := b.UpdateOrderExecutionLimits(context.Background(), "")
err := b.UpdateOrderExecutionLimits(context.Background(), asset.Empty)
if err != nil {
t.Fatal(err)
}

View File

@@ -212,7 +212,7 @@ func (b *Bithumb) Run() {
b.PrintEnabledPairs()
}
err := b.UpdateOrderExecutionLimits(context.TODO(), "")
err := b.UpdateOrderExecutionLimits(context.TODO(), asset.Empty)
if err != nil {
log.Errorf(log.ExchangeSys,
"%s failed to set exchange order execution limits. Err: %v",

View File

@@ -43,18 +43,18 @@ func TestGetSnapshot(t *testing.T) {
func TestCanTradePair(t *testing.T) {
t.Parallel()
err := (*States)(nil).CanTradePair(currency.EMPTYPAIR, "")
err := (*States)(nil).CanTradePair(currency.EMPTYPAIR, asset.Empty)
if !errors.Is(err, errNilStates) {
t.Fatalf("received: %v, but expected: %v", err, errNilStates)
}
err = (&States{}).CanTradePair(currency.EMPTYPAIR, "")
err = (&States{}).CanTradePair(currency.EMPTYPAIR, asset.Empty)
if !errors.Is(err, errEmptyCurrency) {
t.Fatalf("received: %v, but expected: %v", err, errEmptyCurrency)
}
cp := currency.NewPair(currency.BTC, currency.USD)
err = (&States{}).CanTradePair(cp, "")
err = (&States{}).CanTradePair(cp, asset.Empty)
if !errors.Is(err, asset.ErrNotSupported) {
t.Fatalf("received: %v, but expected: %v", err, asset.ErrNotSupported)
}
@@ -115,11 +115,11 @@ func TestCanTradePair(t *testing.T) {
func TestStatesCanTrade(t *testing.T) {
t.Parallel()
err := (*States)(nil).CanTrade(currency.EMPTYCODE, "")
err := (*States)(nil).CanTrade(currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errNilStates) {
t.Fatalf("received: %v, but expected: %v", err, errNilStates)
}
err = (&States{}).CanTrade(currency.EMPTYCODE, "")
err = (&States{}).CanTrade(currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errEmptyCurrency) {
t.Fatalf("received: %v, but expected: %v", err, errEmptyCurrency)
}
@@ -127,11 +127,11 @@ func TestStatesCanTrade(t *testing.T) {
func TestStatesCanWithdraw(t *testing.T) {
t.Parallel()
err := (*States)(nil).CanWithdraw(currency.EMPTYCODE, "")
err := (*States)(nil).CanWithdraw(currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errNilStates) {
t.Fatalf("received: %v, but expected: %v", err, errNilStates)
}
err = (&States{}).CanWithdraw(currency.EMPTYCODE, "")
err = (&States{}).CanWithdraw(currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errEmptyCurrency) {
t.Fatalf("received: %v, but expected: %v", err, errEmptyCurrency)
}
@@ -161,11 +161,11 @@ func TestStatesCanWithdraw(t *testing.T) {
func TestStatesCanDeposit(t *testing.T) {
t.Parallel()
err := (*States)(nil).CanDeposit(currency.EMPTYCODE, "")
err := (*States)(nil).CanDeposit(currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errNilStates) {
t.Fatalf("received: %v, but expected: %v", err, errNilStates)
}
err = (&States{}).CanDeposit(currency.EMPTYCODE, "")
err = (&States{}).CanDeposit(currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errEmptyCurrency) {
t.Fatalf("received: %v, but expected: %v", err, errEmptyCurrency)
}
@@ -195,12 +195,12 @@ func TestStatesCanDeposit(t *testing.T) {
func TestStatesUpdateAll(t *testing.T) {
t.Parallel()
err := (*States)(nil).UpdateAll("", nil)
err := (*States)(nil).UpdateAll(asset.Empty, nil)
if !errors.Is(err, errNilStates) {
t.Fatalf("received: %v, but expected: %v", err, errNilStates)
}
err = (&States{}).UpdateAll("", nil)
err = (&States{}).UpdateAll(asset.Empty, nil)
if !errors.Is(err, asset.ErrNotSupported) {
t.Fatalf("received: %v, but expected: %v", err, asset.ErrNotSupported)
}
@@ -246,17 +246,17 @@ func TestStatesUpdateAll(t *testing.T) {
func TestStatesUpdate(t *testing.T) {
t.Parallel()
err := (*States)(nil).Update(currency.EMPTYCODE, "", Options{})
err := (*States)(nil).Update(currency.EMPTYCODE, asset.Empty, Options{})
if !errors.Is(err, errNilStates) {
t.Fatalf("received: %v, but expected: %v", err, errNilStates)
}
err = (&States{}).Update(currency.EMPTYCODE, "", Options{})
err = (&States{}).Update(currency.EMPTYCODE, asset.Empty, Options{})
if !errors.Is(err, errEmptyCurrency) {
t.Fatalf("received: %v, but expected: %v", err, errEmptyCurrency)
}
err = (&States{}).Update(currency.BTC, "", Options{})
err = (&States{}).Update(currency.BTC, asset.Empty, Options{})
if !errors.Is(err, asset.ErrNotSupported) {
t.Fatalf("received: %v, but expected: %v", err, asset.ErrNotSupported)
}
@@ -273,17 +273,17 @@ func TestStatesUpdate(t *testing.T) {
func TestStatesGet(t *testing.T) {
t.Parallel()
_, err := (*States)(nil).Get(currency.EMPTYCODE, "")
_, err := (*States)(nil).Get(currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errNilStates) {
t.Fatalf("received: %v, but expected: %v", err, errNilStates)
}
_, err = (&States{}).Get(currency.EMPTYCODE, "")
_, err = (&States{}).Get(currency.EMPTYCODE, asset.Empty)
if !errors.Is(err, errEmptyCurrency) {
t.Fatalf("received: %v, but expected: %v", err, errEmptyCurrency)
}
_, err = (&States{}).Get(currency.BTC, "")
_, err = (&States{}).Get(currency.BTC, asset.Empty)
if !errors.Is(err, asset.ErrNotSupported) {
t.Fatalf("received: %v, but expected: %v", err, asset.ErrNotSupported)
}

View File

@@ -165,13 +165,13 @@ func (b *Base) GetPairAssetType(c currency.Pair) (asset.Item, error) {
for i := range assetTypes {
avail, err := b.GetAvailablePairs(assetTypes[i])
if err != nil {
return "", err
return asset.Empty, err
}
if avail.Contains(c, true) {
return assetTypes[i], nil
}
}
return "", errors.New("asset type not associated with currency pair")
return asset.Empty, errors.New("asset type not associated with currency pair")
}
// GetClientBankAccounts returns banking details associated with
@@ -366,7 +366,7 @@ func (b *Base) GetRequestFormattedPairAndAssetType(p string) (currency.Pair, ass
}
}
}
return currency.EMPTYPAIR, "", fmt.Errorf("%s %w", p, currency.ErrPairNotFound)
return currency.EMPTYPAIR, asset.Empty, fmt.Errorf("%s %w", p, currency.ErrPairNotFound)
}
// GetAvailablePairs is a method that returns the available currency pairs

View File

@@ -1643,7 +1643,7 @@ func TestStoreAssetPairFormat(t *testing.T) {
Config: &config.Exchange{Name: "kitties"},
}
err := b.StoreAssetPairFormat(asset.Item(""), currency.PairStore{})
err := b.StoreAssetPairFormat(asset.Empty, currency.PairStore{})
if err == nil {
t.Error("error cannot be nil")
}
@@ -1679,12 +1679,12 @@ func TestSetGlobalPairsManager(t *testing.T) {
Config: &config.Exchange{Name: "kitties"},
}
err := b.SetGlobalPairsManager(nil, nil, "")
err := b.SetGlobalPairsManager(nil, nil, asset.Empty)
if err == nil {
t.Error("error cannot be nil")
}
err = b.SetGlobalPairsManager(&currency.PairFormat{Uppercase: true}, nil, "")
err = b.SetGlobalPairsManager(&currency.PairFormat{Uppercase: true}, nil, asset.Empty)
if err == nil {
t.Error("error cannot be nil")
}
@@ -1696,7 +1696,7 @@ func TestSetGlobalPairsManager(t *testing.T) {
}
err = b.SetGlobalPairsManager(&currency.PairFormat{Uppercase: true},
&currency.PairFormat{Uppercase: true}, "")
&currency.PairFormat{Uppercase: true}, asset.Empty)
if err == nil {
t.Error("error cannot be nil")
}

View File

@@ -1736,7 +1736,7 @@ func TestStakeRequest(t *testing.T) {
func TestUpdateOrderExecutionLimits(t *testing.T) {
t.Parallel()
err := f.UpdateOrderExecutionLimits(context.Background(), "")
err := f.UpdateOrderExecutionLimits(context.Background(), asset.Empty)
if err != nil {
t.Fatal(err)
}

View File

@@ -243,7 +243,7 @@ func (f *FTX) Run() {
f.PrintEnabledPairs()
}
err := f.UpdateOrderExecutionLimits(context.TODO(), "")
err := f.UpdateOrderExecutionLimits(context.TODO(), asset.Empty)
if err != nil {
log.Errorf(log.ExchangeSys,
"%s failed to set exchange order execution limits. Err: %v",

View File

@@ -604,7 +604,7 @@ func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency
return orderDetail, errors.New("failed to get open orders")
}
if assetType == "" {
if assetType == asset.Empty {
assetType = asset.Spot
}

View File

@@ -1060,6 +1060,6 @@ func (o *OKGroup) GetAssetTypeFromTableName(table string) asset.Item {
log.Warnf(log.ExchangeSys, "%s unhandled asset type %s",
o.Name,
table[:assetIndex])
return asset.Item(table[:assetIndex])
return asset.Empty
}
}

View File

@@ -397,15 +397,15 @@ func (o *OKGroup) CancelAllOrders(ctx context.Context, orderCancellation *order.
// GetOrderInfo returns order information based on order ID
func (o *OKGroup) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (resp order.Detail, err error) {
if assetType != asset.Spot {
return resp, fmt.Errorf("%s %w", assetType, asset.ErrNotSupported)
}
mOrder, err := o.GetSpotOrder(ctx, GetSpotOrderRequest{OrderID: orderID})
if err != nil {
return
}
if assetType == "" {
assetType = asset.Spot
}
format, err := o.GetPairFormat(assetType, false)
if err != nil {
return resp, err

View File

@@ -726,7 +726,6 @@ func TestUpdateOrderFromModify(t *testing.T) {
Type: "",
Side: "",
Status: "",
AssetType: "",
Date: time.Time{},
LastUpdated: time.Time{},
Pair: currency.EMPTYPAIR,
@@ -763,7 +762,7 @@ func TestUpdateOrderFromModify(t *testing.T) {
Type: "1",
Side: "1",
Status: "1",
AssetType: "1",
AssetType: 1,
LastUpdated: updated,
Pair: pair,
Trades: []TradeHistory{},
@@ -836,7 +835,7 @@ func TestUpdateOrderFromModify(t *testing.T) {
if od.Status != "1" {
t.Error("Failed to update")
}
if od.AssetType != "1" {
if od.AssetType != 1 {
t.Error("Failed to update")
}
if od.LastUpdated != updated {
@@ -918,7 +917,6 @@ func TestUpdateOrderFromDetail(t *testing.T) {
Type: "",
Side: "",
Status: "",
AssetType: "",
Date: time.Time{},
LastUpdated: time.Time{},
Pair: currency.EMPTYPAIR,
@@ -955,7 +953,7 @@ func TestUpdateOrderFromDetail(t *testing.T) {
Type: "1",
Side: "1",
Status: "1",
AssetType: "1",
AssetType: 1,
LastUpdated: updated,
Pair: pair,
Trades: []TradeHistory{},
@@ -1028,7 +1026,7 @@ func TestUpdateOrderFromDetail(t *testing.T) {
if od.Status != "1" {
t.Error("Failed to update")
}
if od.AssetType != "1" {
if od.AssetType != 1 {
t.Error("Failed to update")
}
if od.LastUpdated != updated {

View File

@@ -10,6 +10,7 @@ import (
"github.com/gofrs/uuid"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/validate"
)
@@ -25,7 +26,7 @@ func (s *Submit) Validate(opt ...validate.Checker) error {
return ErrPairIsEmpty
}
if s.AssetType == "" {
if s.AssetType == asset.Empty {
return ErrAssetNotSet
}
@@ -156,7 +157,7 @@ func (d *Detail) UpdateOrderFromDetail(m *Detail) {
d.Status = m.Status
updated = true
}
if m.AssetType != "" && m.AssetType != d.AssetType {
if m.AssetType != asset.Empty && m.AssetType != d.AssetType {
d.AssetType = m.AssetType
updated = true
}
@@ -320,7 +321,7 @@ func (d *Detail) UpdateOrderFromModify(m *Modify) {
d.Status = m.Status
updated = true
}
if m.AssetType != "" && m.AssetType != d.AssetType {
if m.AssetType != asset.Empty && m.AssetType != d.AssetType {
d.AssetType = m.AssetType
updated = true
}
@@ -391,7 +392,7 @@ func (d *Detail) MatchFilter(f *Filter) bool {
if f.Exchange != "" && !strings.EqualFold(d.Exchange, f.Exchange) {
return false
}
if f.AssetType != "" && d.AssetType != f.AssetType {
if f.AssetType != asset.Empty && d.AssetType != f.AssetType {
return false
}
if !f.Pair.IsEmpty() && !d.Pair.Equal(f.Pair) {
@@ -879,7 +880,7 @@ func (c *Cancel) PairAssetRequired() validate.Checker {
return ErrPairIsEmpty
}
if c.AssetType == "" {
if c.AssetType == asset.Empty {
return ErrAssetNotSet
}
return nil

View File

@@ -44,7 +44,7 @@ func TestRetrieve(t *testing.T) {
d.options = options{
exchange: "THE BIG ONE!!!!!!",
pair: currency.NewPair(currency.THETA, currency.USD),
asset: "Silly asset",
asset: asset.DownsideProfitContract,
lastUpdated: time.Now(),
lastUpdateID: 1337,
priceDuplication: true,

View File

@@ -229,7 +229,7 @@ func TestGetOrderbook(t *testing.T) {
t.Error(err)
}
_, err = Get("Exchange", newCurrency, "meowCats")
_, err = Get("Exchange", newCurrency, asset.Empty)
if err == nil {
t.Error("error cannot be nil")
}
@@ -288,7 +288,7 @@ func TestGetDepth(t *testing.T) {
t.Error(err)
}
_, err = GetDepth("Exchange", newCurrency, "meowCats")
_, err = GetDepth("Exchange", newCurrency, asset.Empty)
if !errors.Is(err, errCannotFindOrderbook) {
t.Fatalf("expecting %s error but received %v", errCannotFindOrderbook, err)
}
@@ -307,7 +307,7 @@ func TestDeployDepth(t *testing.T) {
if !errors.Is(err, errPairNotSet) {
t.Fatalf("expecting %s error but received %v", errPairNotSet, err)
}
_, err = DeployDepth("test", c, "")
_, err = DeployDepth("test", c, asset.Empty)
if !errors.Is(err, errAssetTypeNotSet) {
t.Fatalf("expecting %s error but received %v", errAssetTypeNotSet, err)
}
@@ -434,13 +434,13 @@ func TestProcessOrderbook(t *testing.T) {
}
base.Asks = []Item{{Price: 200, Amount: 200}}
base.Asset = "monthly"
base.Asset = asset.Spot
err = base.Process()
if err != nil {
t.Error("Process() error", err)
}
result, err = Get("ProcessOrderbook", c, "monthly")
result, err = Get("ProcessOrderbook", c, asset.Spot)
if err != nil {
t.Fatal("TestProcessOrderbook failed to retrieve new orderbook")
}
@@ -452,13 +452,13 @@ func TestProcessOrderbook(t *testing.T) {
base.Bids = []Item{{Price: 420, Amount: 200}}
base.Exchange = "Blah"
base.Asset = "quarterly"
base.Asset = asset.CoinMarginedFutures
err = base.Process()
if err != nil {
t.Error("Process() error", err)
}
_, err = Get("Blah", c, "quarterly")
_, err = Get("Blah", c, asset.CoinMarginedFutures)
if err != nil {
t.Fatal("TestProcessOrderbook failed to create new orderbook")
}

View File

@@ -53,7 +53,7 @@ func (b ByVolume) Swap(i, j int) {
// Add adds or updates the item stats
func Add(exchange string, p currency.Pair, a asset.Item, price, volume float64) error {
if exchange == "" ||
a == "" ||
a == asset.Empty ||
price == 0 ||
volume == 0 ||
p.Base.IsEmpty() ||

View File

@@ -127,7 +127,7 @@ func TestAdd(t *testing.T) {
t.Error("stats Add did not add exchange info.")
}
err = Add("", p, "", 0, 0)
err = Add("", p, asset.Empty, 0, 0)
if err == nil {
t.Fatal("error cannot be nil")
}

View File

@@ -129,7 +129,7 @@ func ProcessTicker(p *Price) error {
return fmt.Errorf("%s %s", p.ExchangeName, errPairNotSet)
}
if p.AssetType == "" {
if p.AssetType == asset.Empty {
return fmt.Errorf("%s %s %s",
p.ExchangeName,
p.Pair,

View File

@@ -29,7 +29,7 @@ func TestMain(m *testing.M) {
var cpyMux *dispatch.Mux
func TestSubscribeTicker(t *testing.T) {
_, err := SubscribeTicker("", currency.EMPTYPAIR, asset.Item(""))
_, err := SubscribeTicker("", currency.EMPTYPAIR, asset.Empty)
if err == nil {
t.Error("error cannot be nil")
}
@@ -68,7 +68,7 @@ func TestSubscribeTicker(t *testing.T) {
err = ProcessTicker(&Price{
Pair: sillyP,
ExchangeName: "subscribetest",
AssetType: "silly",
AssetType: asset.DownsideProfitContract,
})
if err == nil {
t.Error("error cannot be nil")
@@ -166,13 +166,13 @@ func TestGetTicker(t *testing.T) {
priceStruct.PriceATH = 9001
priceStruct.Pair.Base = currency.ETH
priceStruct.AssetType = "futures_3m"
priceStruct.AssetType = asset.DownsideProfitContract
err = ProcessTicker(&priceStruct)
if err != nil {
t.Fatal("ProcessTicker error", err)
}
tickerPrice, err = GetTicker("bitfinex", newPair, "futures_3m")
tickerPrice, err = GetTicker("bitfinex", newPair, asset.DownsideProfitContract)
if err != nil {
t.Errorf("Ticker GetTicker init error: %s", err)
}
@@ -181,12 +181,12 @@ func TestGetTicker(t *testing.T) {
t.Error("ticker tickerPrice.PriceATH value is incorrect")
}
_, err = GetTicker("bitfinex", newPair, "meowCats")
_, err = GetTicker("bitfinex", newPair, asset.UpsideProfitContract)
if err == nil {
t.Error("Ticker GetTicker error cannot be nil")
}
priceStruct.AssetType = "meowCats"
priceStruct.AssetType = asset.UpsideProfitContract
err = ProcessTicker(&priceStruct)
if err != nil {
t.Fatal("ProcessTicker error", err)

View File

@@ -202,24 +202,22 @@ func tradeToSQLData(trades ...Data) ([]tradesql.Data, error) {
}
// SQLDataToTrade converts sql data to glorious trade data
func SQLDataToTrade(dbTrades ...tradesql.Data) (result []Data, err error) {
func SQLDataToTrade(dbTrades ...tradesql.Data) ([]Data, error) {
result := make([]Data, len(dbTrades))
for i := range dbTrades {
var cp currency.Pair
cp, err = currency.NewPairFromStrings(dbTrades[i].Base, dbTrades[i].Quote)
cp, err := currency.NewPairFromStrings(dbTrades[i].Base, dbTrades[i].Quote)
if err != nil {
return nil, err
}
cp = cp.Upper()
var a = asset.Item(dbTrades[i].AssetType)
if !a.IsValid() {
return nil, fmt.Errorf("invalid asset type %v", a)
}
var s order.Side
s, err = order.StringToOrderSide(dbTrades[i].Side)
a, err := asset.New(dbTrades[i].AssetType)
if err != nil {
return nil, err
}
result = append(result, Data{
s, err := order.StringToOrderSide(dbTrades[i].Side)
if err != nil {
return nil, err
}
result[i] = Data{
ID: uuid.FromStringOrNil(dbTrades[i].ID),
Timestamp: dbTrades[i].Timestamp.UTC(),
Exchange: dbTrades[i].Exchange,
@@ -228,7 +226,7 @@ func SQLDataToTrade(dbTrades ...tradesql.Data) (result []Data, err error) {
Price: dbTrades[i].Price,
Amount: dbTrades[i].Amount,
Side: s,
})
}
}
return result, nil
}

View File

@@ -979,11 +979,11 @@ func Test_FormatExchangeKlineInterval(t *testing.T) {
}
func TestValidateCandlesRequest(t *testing.T) {
_, err := z.validateCandlesRequest(currency.EMPTYPAIR, "", time.Time{}, time.Time{}, kline.Interval(-1))
_, err := z.validateCandlesRequest(currency.EMPTYPAIR, asset.Empty, time.Time{}, time.Time{}, kline.Interval(-1))
if !errors.Is(err, common.ErrDateUnset) {
t.Error(err)
}
_, err = z.validateCandlesRequest(currency.EMPTYPAIR, "", time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC), time.Time{}, kline.Interval(-1))
_, err = z.validateCandlesRequest(currency.EMPTYPAIR, asset.Empty, time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC), time.Time{}, kline.Interval(-1))
if !errors.Is(err, common.ErrDateUnset) {
t.Error(err)
}

View File

@@ -180,7 +180,7 @@ func (w Wrapper) CancelOrder(ctx context.Context, exch, orderid string, cp curre
if !cp.IsEmpty() && cp.IsInvalid() {
return false, errTestFailed
}
if a != "" && !a.IsValid() {
if a != asset.Empty && !a.IsValid() {
return false, errTestFailed
}
return true, nil

View File

@@ -105,7 +105,7 @@ func TestWrapper_CancelOrder(t *testing.T) {
}
_, err = testWrapper.CancelOrder(context.Background(),
exchName, orderID, cp, "")
exchName, orderID, cp, asset.Empty)
if err != nil {
t.Error(err)
}