Skip to content

Commit

Permalink
Further shaznits
Browse files Browse the repository at this point in the history
  • Loading branch information
cranktakular committed Nov 12, 2024
1 parent 2cc9d0c commit 2fd8bb1
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 312 deletions.
73 changes: 12 additions & 61 deletions exchanges/coinbasepro/coinbasepro.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@ const (
startDateString = "start_date"
endDateString = "end_date"

errIntervalNotSupported = "interval not supported"
warnSequenceIssue = "Out of order sequence number. Received %v, expected %v"
warnAuth = "%v authenticated request failed, attempting unauthenticated"
warnSequenceIssue = "Out of order sequence number. Received %v, expected %v"
warnAuth = "%v authenticated request failed, attempting unauthenticated"

manyFills = 65535
manyOrds = 2147483647
Expand Down Expand Up @@ -155,6 +154,7 @@ var (
errUnrecognisedOrderType = errors.New("unrecognised order type")
errUnrecognisedAssetType = errors.New("unrecognised asset type")
errUnrecognisedStrategyType = errors.New("unrecognised strategy type")
errIntervalNotSupported = errors.New("interval not supported")

allowedGranularities = []string{granOneMin, granFiveMin, granFifteenMin, granThirtyMin, granOneHour, granTwoHour, granSixHour, granOneDay}
closedStatuses = []string{"FILLED", "CANCELLED", "EXPIRED", "FAILED"}
Expand Down Expand Up @@ -199,23 +199,24 @@ func (c *CoinbasePro) GetBestBidAsk(ctx context.Context, products []string) ([]P
}

// GetProductBookV3 returns a list of bids/asks for a single product
func (c *CoinbasePro) GetProductBookV3(ctx context.Context, productID string, limit uint16, authenticated bool) (*ProductBook, error) {
if productID == "" {
func (c *CoinbasePro) GetProductBookV3(ctx context.Context, productID currency.Pair, limit uint16, aggregationIncrement float64, authenticated bool) (*ProductBookResp, error) {
if productID.IsEmpty() {
return nil, errProductIDEmpty
}
vals := url.Values{}
vals.Set("product_id", productID)
vals.Set("product_id", productID.String())
if limit != 0 {
vals.Set("limit", strconv.FormatInt(int64(limit), 10))
}
resp := struct {
Pricebook ProductBook `json:"pricebook"`
}{}
if aggregationIncrement != 0 {
vals.Set("aggregation_price_increment", strconv.FormatFloat(aggregationIncrement, 'f', -1, 64))
}
var resp *ProductBookResp
if authenticated {
return &resp.Pricebook, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseV3+coinbaseProductBook, vals, nil, true, &resp, nil)
return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseV3+coinbaseProductBook, vals, nil, true, &resp, nil)
}
path := coinbaseV3 + coinbaseMarket + "/" + coinbaseProductBook
return &resp.Pricebook, c.SendHTTPRequest(ctx, exchange.RestSpot, path, vals, &resp)
return resp, c.SendHTTPRequest(ctx, exchange.RestSpot, path, vals, &resp)
}

// GetAllProducts returns information on all currency pairs that are available for trading
Expand Down Expand Up @@ -1659,53 +1660,3 @@ func (f FiatTransferType) String() string {
}
return "deposit"
}

// UnmarshalJSON unmarshals the JSON input into a UnixTimestamp type
func (t *UnixTimestamp) UnmarshalJSON(b []byte) error {
var timestampStr string
err := json.Unmarshal(b, &timestampStr)
if err != nil {
return err
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
return err
}
*t = UnixTimestamp(time.Unix(timestamp, 0).UTC())
return nil
}

// String implements the stringer interface
func (t *UnixTimestamp) String() string {
return t.Time().String()
}

// Time returns the time.Time representation of the UnixTimestamp
func (t *UnixTimestamp) Time() time.Time {
return time.Time(*t)
}

// UnmarshalJSON unmarshals the JSON input into a UnixTimestamp type
func (t *UnixTimestampMilli) UnmarshalJSON(b []byte) error {
var timestampStr string
err := json.Unmarshal(b, &timestampStr)
if err != nil {
return err
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
return err
}
*t = UnixTimestampMilli(time.UnixMilli(timestamp).UTC())
return nil
}

// String implements the stringer interface
func (t *UnixTimestampMilli) String() string {
return t.Time().String()
}

// Time returns the time.Time representation of the UnixTimestamp
func (t *UnixTimestampMilli) Time() time.Time {
return time.Time(*t)
}
43 changes: 13 additions & 30 deletions exchanges/coinbasepro/coinbasepro_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,13 @@ func TestGetBestBidAsk(t *testing.T) {

func TestGetProductBookV3(t *testing.T) {
t.Parallel()
_, err := c.GetProductBookV3(context.Background(), "", 0, false)
_, err := c.GetProductBookV3(context.Background(), currency.Pair{}, 0, 0, false)
assert.ErrorIs(t, err, errProductIDEmpty)
resp, err := c.GetProductBookV3(context.Background(), testPair.String(), 2, false)
resp, err := c.GetProductBookV3(context.Background(), testPair, 4, -1, false)
assert.NoError(t, err)
assert.NotEmpty(t, resp, errExpectedNonEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, c)
resp, err = c.GetProductBookV3(context.Background(), testPair.String(), 2, true)
resp, err = c.GetProductBookV3(context.Background(), testPair, 4, -1, true)
assert.NoError(t, err)
assert.NotEmpty(t, resp, errExpectedNonEmpty)
}
Expand Down Expand Up @@ -970,7 +970,7 @@ func TestSendAuthenticatedHTTPRequest(t *testing.T) {
err = c.SendAuthenticatedHTTPRequest(context.Background(), exchange.EdgeCase3, "", "", nil, nil, false, nil, nil)
assert.ErrorIs(t, err, exchange.ErrEndpointPathNotFound)
ch := make(chan struct{})
body := map[string]interface{}{"Unmarshalable": ch}
body := map[string]any{"Unmarshalable": ch}
err = c.SendAuthenticatedHTTPRequest(context.Background(), exchange.RestSpot, "", "", nil, body, false, nil, nil)
var targetErr *json.UnsupportedTypeError
assert.ErrorAs(t, err, &targetErr)
Expand Down Expand Up @@ -1072,13 +1072,17 @@ func TestUpdateTicker(t *testing.T) {

func TestFetchTicker(t *testing.T) {
t.Parallel()
_, err := c.FetchTicker(context.Background(), currency.Pair{}, asset.Spot)
assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
resp, err := c.FetchTicker(context.Background(), testPair, asset.Spot)
assert.NoError(t, err)
assert.NotEmpty(t, resp, errExpectedNonEmpty)
}

func TestFetchOrderbook(t *testing.T) {
t.Parallel()
_, err := c.FetchOrderbook(context.Background(), currency.Pair{}, asset.Empty)
assert.ErrorIs(t, err, currency.ErrCurrencyPairEmpty)
resp, err := c.FetchOrderbook(context.Background(), testPair, asset.Spot)
assert.NoError(t, err)
assert.NotEmpty(t, resp, errExpectedNonEmpty)
Expand Down Expand Up @@ -1427,29 +1431,6 @@ func TestFiatTransferTypeString(t *testing.T) {
}
}

func TestUnixTimestampUnmarshalJSON(t *testing.T) {
t.Parallel()
var u UnixTimestamp
err := u.UnmarshalJSON([]byte("0"))
var targetErr *json.UnmarshalTypeError
assert.ErrorAs(t, err, &targetErr)
err = u.UnmarshalJSON([]byte("\"922337203685477580700\""))
assert.ErrorIs(t, err, strconv.ErrRange)
err = u.UnmarshalJSON([]byte("\"1234\""))
assert.NoError(t, err)
}

func TestUnixTimestampString(t *testing.T) {
t.Parallel()
var u UnixTimestamp
err := u.UnmarshalJSON([]byte("\"1234\""))
assert.NoError(t, err)
s := u.String()
if s != expectedTimestamp {
t.Errorf(errExpectMismatch, s, expectedTimestamp)
}
}

func TestFormatExchangeKlineIntervalV3(t *testing.T) {
t.Parallel()
testSequence := map[kline.Interval]string{
Expand All @@ -1460,12 +1441,15 @@ func TestFormatExchangeKlineIntervalV3(t *testing.T) {
kline.TwoHour: granTwoHour,
kline.SixHour: granSixHour,
kline.OneDay: granOneDay,
kline.OneWeek: errIntervalNotSupported}
kline.OneWeek: ""}
for k := range testSequence {
resp := FormatExchangeKlineIntervalV3(k)
resp, err := FormatExchangeKlineIntervalV3(k)
if resp != testSequence[k] {
t.Errorf(errExpectMismatch, resp, testSequence[k])
}
if resp == "" {
assert.ErrorIs(t, err, errIntervalNotSupported)
}
}
}

Expand Down Expand Up @@ -1524,7 +1508,6 @@ func TestCancelPendingFuturesSweep(t *testing.T) {

// TestWsAuth dials websocket, sends login request.
func TestWsAuth(t *testing.T) {
// t.Parallel()
p := currency.Pairs{testPair}
if c.Websocket.IsEnabled() && !c.API.AuthenticatedWebsocketSupport || !sharedtestvalues.AreAPICredentialsSet(c) {
t.Skip(stream.ErrWebsocketNotEnabled.Error())
Expand Down
Loading

0 comments on commit 2fd8bb1

Please sign in to comment.