diff --git a/README.md b/README.md index dd1b65e..30bcb01 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Client will respect environment variables: COINBASE_PRO_BASEURL, COINBASE_PRO_PA ```go import ( - coinbasepro "github.com/preichenberger/go-coinbasepro/v2" + coinbasepro "github.com/preichenberger/go-coinbasepro" ) client := coinbasepro.NewClient() @@ -187,7 +187,7 @@ Results return coinbase time type which handles different types of time parsing ```go import( "time" - coinbasepro "github.com/preichenberger/go-coinbasepro/v2" + coinbasepro "github.com/preichenberger/go-coinbasepro" ) coinbaseTime := coinbasepro.Time{} diff --git a/client.go b/client.go index a2c8390..767263a 100644 --- a/client.go +++ b/client.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "math" "net/http" "os" "strconv" @@ -17,7 +16,6 @@ type Client struct { Key string Passphrase string HTTPClient *http.Client - RetryCount int } type ClientConfig struct { @@ -41,7 +39,6 @@ func NewClient() *Client { HTTPClient: &http.Client{ Timeout: 15 * time.Second, }, - RetryCount: 0, } if os.Getenv("COINBASE_PRO_SANDBOX") == "1" { @@ -75,19 +72,15 @@ func (c *Client) UpdateConfig(config *ClientConfig) { func (c *Client) Request(method string, url string, params, result interface{}) (res *http.Response, err error) { - for i := 0; i < c.RetryCount+1; i++ { - retryDuration := time.Duration((math.Pow(2, float64(i))-1)/2*1000) * time.Millisecond - time.Sleep(retryDuration) - - res, err = c.request(method, url, params, result) - if res != nil && res.StatusCode == 429 { - continue - } else { - break - } + + if err = BeforeRequest(c, method, fmt.Sprintf("%s%s", c.BaseURL, url)); err != nil { + return nil, err } + defer func() { + AfterRequest() + }() - return res, err + return c.request(method, url, params, result) } func (c *Client) request(method string, url string, diff --git a/go.mod b/go.mod index 3e00d39..580716d 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ -module github.com/preichenberger/go-coinbasepro/v2 +module github.com/svanas/go-coinbasepro require github.com/gorilla/websocket v1.4.0 diff --git a/message.go b/message.go index 8f0eb39..68a011a 100644 --- a/message.go +++ b/message.go @@ -7,38 +7,38 @@ import ( type Message struct { Type string `json:"type"` ProductID string `json:"product_id"` - ProductIds []string `json:"product_ids"` - Products []Product `json:"products"` - Currencies []Currency `json:"currencies"` - TradeID int `json:"trade_id,number"` - OrderID string `json:"order_id"` - ClientOID string `json:"client_oid"` - Sequence int64 `json:"sequence,number"` - MakerOrderID string `json:"maker_order_id"` - TakerOrderID string `json:"taker_order_id"` - Time Time `json:"time,string"` - RemainingSize string `json:"remaining_size"` - NewSize string `json:"new_size"` - OldSize string `json:"old_size"` - Size string `json:"size"` - Price string `json:"price"` - Side string `json:"side"` - Reason string `json:"reason"` - OrderType string `json:"order_type"` - Funds string `json:"funds"` - NewFunds string `json:"new_funds"` - OldFunds string `json:"old_funds"` - Message string `json:"message"` + ProductIds []string `json:"product_ids,omitempty"` + Products []Product `json:"products,omitempty"` + Currencies []Currency `json:"currencies,omitempty"` + TradeID int `json:"trade_id,number,omitempty"` + OrderID string `json:"order_id,omitempty"` + ClientOID string `json:"client_oid,omitempty"` + Sequence int64 `json:"sequence,number,omitempty"` + MakerOrderID string `json:"maker_order_id,omitempty"` + TakerOrderID string `json:"taker_order_id,omitempty"` + Time Time `json:"time,string,omitempty"` + RemainingSize string `json:"remaining_size,omitempty"` + NewSize string `json:"new_size,omitempty"` + OldSize string `json:"old_size,omitempty"` + Size string `json:"size,omitempty"` + Price string `json:"price,omitempty"` + Side string `json:"side,omitempty"` + Reason string `json:"reason,omitempty"` + OrderType string `json:"order_type,omitempty"` + Funds string `json:"funds,omitempty"` + NewFunds string `json:"new_funds,omitempty"` + OldFunds string `json:"old_funds,omitempty"` + Message string `json:"message,omitempty"` Bids []SnapshotEntry `json:"bids,omitempty"` Asks []SnapshotEntry `json:"asks,omitempty"` Changes []SnapshotChange `json:"changes,omitempty"` - LastSize string `json:"last_size"` - BestBid string `json:"best_bid"` - BestAsk string `json:"best_ask"` - Channels []MessageChannel `json:"channels"` - UserID string `json:"user_id"` - ProfileID string `json:"profile_id"` - LastTradeID int `json:"last_trade_id"` + LastSize string `json:"last_size,omitempty"` + BestBid string `json:"best_bid,omitempty"` + BestAsk string `json:"best_ask,omitempty"` + Channels []MessageChannel `json:"channels,omitempty"` + UserID string `json:"user_id,omitempty"` + ProfileID string `json:"profile_id,omitempty"` + LastTradeID int `json:"last_trade_id,omitempty"` } type MessageChannel struct { diff --git a/order.go b/order.go index 08dc4b8..84e5dcb 100644 --- a/order.go +++ b/order.go @@ -22,7 +22,7 @@ type Order struct { Funds string `json:"funds,omitempty"` SpecifiedFunds string `json:"specified_funds,omitempty"` // Response Fields - ID string `json:"id"` + ID string `json:"id,omitempty"` Status string `json:"status,omitempty"` Settled bool `json:"settled,omitempty"` DoneReason string `json:"done_reason,omitempty"` diff --git a/product.go b/product.go index 97268ae..45fc621 100644 --- a/product.go +++ b/product.go @@ -10,16 +10,16 @@ import ( ) type Product struct { - ID string `json:"id"` - BaseCurrency string `json:"base_currency"` - QuoteCurrency string `json:"quote_currency"` - BaseMinSize string `json:"base_min_size"` - BaseMaxSize string `json:"base_max_size"` - QuoteIncrement string `json:"quote_increment"` - BaseIncrement string `json:"base_increment"` - DisplayName string `json:"display_name"` - MinMarketFunds string `json:"min_market_funds"` - MaxMarketFunds string `json:"max_market_funds"` + ID string `json:"id"` + BaseCurrency string `json:"base_currency"` + QuoteCurrency string `json:"quote_currency"` + // BaseMinSize string `json:"base_min_size"` deprecated on 2022-06-30, see https://docs.cloud.coinbase.com/exchange/docs/changelog#2022-jun-02 + // BaseMaxSize string `json:"base_max_size"` deprecated on 2022-06-30, see https://docs.cloud.coinbase.com/exchange/docs/changelog#2022-jun-02 + QuoteIncrement string `json:"quote_increment"` + BaseIncrement string `json:"base_increment"` + DisplayName string `json:"display_name"` + MinMarketFunds string `json:"min_market_funds"` + // MaxMarketFunds string `json:"max_market_funds"` deprecated on 2022-06-30, see https://docs.cloud.coinbase.com/exchange/docs/changelog#2022-jun-02 MarginEnabled bool `json:"margin_enabled"` PostOnly bool `json:"post_only"` LimitOnly bool `json:"limit_only"` diff --git a/test_helper.go b/test_helper.go index ff03284..4dd7561 100644 --- a/test_helper.go +++ b/test_helper.go @@ -12,7 +12,6 @@ func NewTestClient() *Client { client.UpdateConfig(&ClientConfig{ BaseURL: "https://api-public.sandbox.pro.coinbase.com", }) - client.RetryCount = 2 return client } diff --git a/throttler.go b/throttler.go new file mode 100644 index 0000000..93f758b --- /dev/null +++ b/throttler.go @@ -0,0 +1,25 @@ +package coinbasepro + +import ( + "time" +) + +var ( + lastRequest time.Time + RequestsPerSecond float64 = 10 + BeforeRequest func(client *Client, method, endpoint string) error = nil + AfterRequest func() = nil +) + +func init() { + BeforeRequest = func(client *Client, method, endpoint string) error { + elapsed := time.Since(lastRequest) + if elapsed.Seconds() < (float64(1) / RequestsPerSecond) { + time.Sleep(time.Duration((float64(time.Second) / RequestsPerSecond)) - elapsed) + } + return nil + } + AfterRequest = func() { + lastRequest = time.Now() + } +}