Skip to content

Commit

Permalink
Deribit: Fix race on Setup with optionsRegex
Browse files Browse the repository at this point in the history
Calling Setup twice would race on the assignment to this package var.

There was an option to just move the assignment to the package var declaration, but this
change improves the performance and allocations:
```
BenchmarkOptionPairToString-8            1000000              1239 ns/op             485 B/op         10 allocs/op
BenchmarkOptionPairToString2-8           3473804               656.2 ns/op           348 B/op          7 allocs/op
```

I've also removed the t.Run because even success the -v output from
tests would be very noisy, and I don't think we were getting any benefit
from it at all:
```
=== RUN   TestOptionPairToString
=== PAUSE TestOptionPairToString
=== CONT  TestOptionPairToString
=== RUN   TestOptionPairToString/BTC-30MAY24-61000-C
=== PAUSE TestOptionPairToString/BTC-30MAY24-61000-C
=== RUN   TestOptionPairToString/ETH-1JUN24-3200-P
=== PAUSE TestOptionPairToString/ETH-1JUN24-3200-P
=== RUN   TestOptionPairToString/SOL_USDC-31MAY24-162-P
=== PAUSE TestOptionPairToString/SOL_USDC-31MAY24-162-P
=== RUN   TestOptionPairToString/MATIC_USDC-6APR24-0d98-P
=== PAUSE TestOptionPairToString/MATIC_USDC-6APR24-0d98-P
=== CONT  TestOptionPairToString/BTC-30MAY24-61000-C
=== CONT  TestOptionPairToString/SOL_USDC-31MAY24-162-P
=== CONT  TestOptionPairToString/ETH-1JUN24-3200-P
=== CONT  TestOptionPairToString/MATIC_USDC-6APR24-0d98-P
--- PASS: TestOptionPairToString (0.00s)
    --- PASS: TestOptionPairToString/BTC-30MAY24-61000-C (0.00s)
    --- PASS: TestOptionPairToString/ETH-1JUN24-3200-P (0.00s)
    --- PASS: TestOptionPairToString/SOL_USDC-31MAY24-162-P (0.00s)
    --- PASS: TestOptionPairToString/MATIC_USDC-6APR24-0d98-P (0.00s)
```

( And that got worse with me adding more tests )
  • Loading branch information
gbjk committed Aug 30, 2024
1 parent bba8757 commit 3bb37fe
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 36 deletions.
33 changes: 12 additions & 21 deletions exchanges/deribit/deribit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"fmt"
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
"time"
Expand All @@ -28,12 +27,6 @@ type Deribit struct {
exchange.Base
}

var (
// optionRegex compiles optionDecimalRegex at startup and is used to help set
// option currency lower-case d eg MATIC-USDC-3JUN24-0d64-P
optionRegex *regexp.Regexp
)

const (
deribitAPIVersion = "/api/v2"
tradeBaseURL = "https://www.deribit.com/"
Expand All @@ -43,8 +36,7 @@ const (
tradeFuturesCombo = "futures-spreads/"
tradeOptionsCombo = "combos/"

perpString = "PERPETUAL"
optionDecimalRegex = `\d+(D)\d+`
perpString = "PERPETUAL"

// Public endpoints
// Market Data
Expand Down Expand Up @@ -2837,20 +2829,19 @@ func (d *Deribit) formatFuturesTradablePair(pair currency.Pair) string {
return instrumentID
}

// optionPairToString to format and return an Options currency pairs with the following format: MATIC_USDC-6APR24-0d98-P
// it has both uppercase or lowercase characters, which we can not achieve with the Upper=true or Upper=false
// optionPairToString formats an options pair as: SYMBOL-EXPIRE-STRIKE-TYPE
// SYMBOL may be a currency (BTC) or a pair (XRP_USDC)
// EXPIRE is DDMMMYY
// STRIKE make include a d for decimal point in linear options
// TYPE is Call or Put
func (d *Deribit) optionPairToString(pair currency.Pair) string {
subCodes := strings.Split(pair.Quote.String(), currency.DashDelimiter)
initialDelimiter := currency.DashDelimiter
if subCodes[0] == "USDC" {
q := pair.Quote.String()
if q[:4] == "USDC" && len(q) > 11 { // Linear option
initialDelimiter = currency.UnderscoreDelimiter
// Replace a capital D with d for decimal place in Strike price
// Char 11 is either the hyphen before Strike price or first digit
q = q[:11] + strings.Replace(q[11:], "D", "d", -1)
}
for i := range subCodes {
if match := optionRegex.MatchString(subCodes[i]); match {
subCodes[i] = strings.ToLower(subCodes[i])
break
}
}

return pair.Base.String() + initialDelimiter + strings.Join(subCodes, currency.DashDelimiter)
return pair.Base.String() + initialDelimiter + q
}
19 changes: 8 additions & 11 deletions exchanges/deribit/deribit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3307,9 +3307,9 @@ func TestGenerateSubscriptions(t *testing.T) {
func TestChannelInterval(t *testing.T) {
t.Parallel()

for _, i := range []int{1, 3, 5, 10, 15, 30, 60, 120, 180, 360, 720} {
a := channelInterval(&subscription.Subscription{Channel: subscription.CandlesChannel, Interval: kline.Interval(i * int(time.Minute))})
assert.Equal(t, strconv.Itoa(i), a)
for _, i := range []int64{1, 3, 5, 10, 15, 30, 60, 120, 180, 360, 720} {
a := channelInterval(&subscription.Subscription{Channel: subscription.CandlesChannel, Interval: kline.Interval(i * int64(time.Minute))})
assert.Equal(t, strconv.Itoa(int(i)), a)
}

a := channelInterval(&subscription.Subscription{Channel: subscription.CandlesChannel, Interval: kline.OneDay})
Expand Down Expand Up @@ -3751,18 +3751,15 @@ func TestFormatFuturesTradablePair(t *testing.T) {

func TestOptionPairToString(t *testing.T) {
t.Parallel()
optionsList := map[currency.Pair]string{
for pair, exp := range map[currency.Pair]string{
{Delimiter: currency.DashDelimiter, Base: currency.BTC, Quote: currency.NewCode("30MAY24-61000-C")}: "BTC-30MAY24-61000-C",
{Delimiter: currency.DashDelimiter, Base: currency.ETH, Quote: currency.NewCode("1JUN24-3200-P")}: "ETH-1JUN24-3200-P",
{Delimiter: currency.DashDelimiter, Base: currency.SOL, Quote: currency.NewCode("USDC-31MAY24-162-P")}: "SOL_USDC-31MAY24-162-P",
{Delimiter: currency.DashDelimiter, Base: currency.MATIC, Quote: currency.NewCode("USDC-6APR24-0d98-P")}: "MATIC_USDC-6APR24-0d98-P",
}
for pair, instrumentID := range optionsList {
t.Run(instrumentID, func(t *testing.T) {
t.Parallel()
instrument := d.optionPairToString(pair)
require.Equal(t, instrumentID, instrument)
})
{Delimiter: currency.DashDelimiter, Base: currency.MATIC, Quote: currency.NewCode("USDC-8JUN24-0D99-P")}: "MATIC_USDC-8JUN24-0d99-P",
{Delimiter: currency.DashDelimiter, Base: currency.MATIC, Quote: currency.NewCode("USDC-6DEC29-0D87-C")}: "MATIC_USDC-6DEC29-0d87-C",
} {
assert.Equal(t, exp, d.optionPairToString(pair), "optionPairToString must return correctly")
}
}

Expand Down
4 changes: 0 additions & 4 deletions exchanges/deribit/deribit_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"regexp"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -188,9 +187,6 @@ func (d *Deribit) Setup(exch *config.Exchange) error {
return err
}

// setup option decimal regex at startup to make constant checks more efficient
optionRegex = regexp.MustCompile(optionDecimalRegex)

return d.Websocket.SetupNewConnection(stream.ConnectionSetup{
URL: d.Websocket.GetWebsocketURL(),
ResponseCheckTimeout: exch.WebsocketResponseCheckTimeout,
Expand Down

0 comments on commit 3bb37fe

Please sign in to comment.