diff --git a/api_trading.go b/api_trading.go index d367516..75b3ff3 100644 --- a/api_trading.go +++ b/api_trading.go @@ -39,6 +39,11 @@ func (c *Client) CancelAllByInstrument(params *models.CancelAllByInstrumentParam return } +func (c *Client) CancelByLabel(params *models.CancelByLabelParams) (result int, err error) { + err = c.Call("private/cancel_by_label", params, &result) + return +} + func (c *Client) ClosePosition(params *models.ClosePositionParams) (result models.ClosePositionResponse, err error) { err = c.Call("private/close_position", params, &result) return @@ -79,6 +84,11 @@ func (c *Client) GetOrderState(params *models.GetOrderStateParams) (result model return } +func (c *Client) GetOrderStateByLabel(params *models.GetOrderStateByLabelParams) (result []models.Order, err error) { + err = c.Call("/private/get_order_state_by_label", params, &result) + return +} + func (c *Client) GetStopOrderHistory(params *models.GetStopOrderHistoryParams) (result models.GetStopOrderHistoryResponse, err error) { err = c.Call("private/get_stop_order_history", params, &result) return @@ -104,7 +114,7 @@ func (c *Client) GetUserTradesByInstrumentAndTime(params *models.GetUserTradesBy return } -func (c *Client) GetUserTradesByOrder(params *models.GetUserTradesByOrderParams) (result models.GetUserTradesResponse, err error) { +func (c *Client) GetUserTradesByOrder(params *models.GetUserTradesByOrderParams) (result []models.Trade, err error) { err = c.Call("private/get_user_trades_by_order", params, &result) return } diff --git a/client_test.go b/client_test.go index d33088f..66f7668 100644 --- a/client_test.go +++ b/client_test.go @@ -2,9 +2,11 @@ package deribit import ( "encoding/json" + "math/rand" + "testing" + "github.com/frankrap/deribit-api/models" "github.com/stretchr/testify/assert" - "testing" ) func newClient() *Client { @@ -36,6 +38,46 @@ func TestClient_Test(t *testing.T) { t.Logf("%v", result) } +func TestClient_GetInstruments_spot(t *testing.T) { + client := newClient() + instruments, err := client.GetInstruments(&models.GetInstrumentsParams{Currency: "BTC", Kind: "spot"}) + assert.Nil(t, err) + assert.True(t, len(instruments) > 0, "No instrument gotten") + for _, instrument := range instruments { + assert.NotEmpty(t, instrument.InstrumentName) + assert.NotEmpty(t, instrument.BaseCurrency) + assert.NotEmpty(t, instrument.ContractSize) + assert.NotEmpty(t, instrument.InstrumentType) + assert.NotEmpty(t, instrument.CounterCurrency) + assert.NotEmpty(t, instrument.CreationTimestamp) + assert.NotEmpty(t, instrument.ExpirationTimestamp) + assert.NotEmpty(t, instrument.Kind) + assert.Truef(t, instrument.CounterCurrency == "BTC" || instrument.BaseCurrency == "BTC", "%+v", instrument) + assert.Equal(t, instrument.Kind, "spot") + } +} + +func TestClient_GetInstruments_future(t *testing.T) { + client := newClient() + instruments, err := client.GetInstruments(&models.GetInstrumentsParams{Currency: "BTC", Kind: "future"}) + assert.Nil(t, err) + assert.True(t, len(instruments) > 0, "No instrument gotten") + for _, instrument := range instruments { + assert.NotEmpty(t, instrument.InstrumentName) + assert.NotEmpty(t, instrument.BaseCurrency) + assert.NotEmpty(t, instrument.ContractSize) + assert.NotEmpty(t, instrument.InstrumentType) + assert.NotEmpty(t, instrument.CounterCurrency) + assert.NotEmpty(t, instrument.CreationTimestamp) + assert.NotEmpty(t, instrument.ExpirationTimestamp) + assert.NotEmpty(t, instrument.SettlementCurrency) + assert.NotEmpty(t, instrument.Kind) + assert.Truef(t, instrument.CounterCurrency == "BTC" || instrument.BaseCurrency == "BTC", "%+v", instrument) + assert.Truef(t, instrument.SettlementCurrency == "BTC", "%+v", instrument) + assert.Equal(t, instrument.Kind, "future") + } +} + func TestClient_GetBookSummaryByCurrency(t *testing.T) { client := newClient() params := &models.GetBookSummaryByCurrencyParams{ @@ -135,6 +177,134 @@ func TestClient_Buy(t *testing.T) { t.Logf("%#v", result) } +func TestClient_CancelByLabel(t *testing.T) { + client := newClient() + params := &models.BuyParams{ + InstrumentName: "BTC-PERPETUAL", + Amount: 10, + Price: 20000.0, + Type: "limit", + Label: "TestClient_CancelByLabel", + } + result, err := client.Buy(params) + if err != nil { + t.Fatal(err) + return + } + + t.Logf("%#v", result) + + cancelByLabelParams := &models.CancelByLabelParams{ + Label: "TestClient_CancelByLabel", + } + + cancelResult, err := client.CancelByLabel(cancelByLabelParams) + if err != nil { + t.Errorf("Cancel failed, %s", err) + } + + if cancelResult <= 0 { + t.Errorf("Cancel order count should be greater than 0, actual=%d", cancelResult) + } + + t.Logf("%#v", cancelResult) +} + +func TestClient_GetUserTradesByOrder(t *testing.T) { + client := newClient() + params := &models.BuyParams{ + InstrumentName: "BTC-PERPETUAL", + Amount: 10, + Price: 20000.0, + Type: "market", + Label: "TestClient_CancelByLabel", + } + buyResult, err := client.Buy(params) + if err != nil { + t.Fatal(err) + } + + t.Logf("%#v", buyResult) + + getTradesRes, err := client.GetUserTradesByOrder(&models.GetUserTradesByOrderParams{OrderID: buyResult.Order.OrderID}) + + if err != nil { + t.Fatal(err) + } + + if actualTradesCount := len(getTradesRes); actualTradesCount == 0 { + t.Errorf("no Trades") + } + + if expectTradesCount, actualTradesCount := len(buyResult.Trades), len(getTradesRes); expectTradesCount != actualTradesCount { + t.Fatalf("Expected trades count %d, actual: %d", expectTradesCount, actualTradesCount) + } + + for i, trade := range buyResult.Trades { + if trade.TradeSeq != getTradesRes[i].TradeSeq { + t.Errorf("Expected TradeSeq %d, actual %d", trade.TradeSeq, getTradesRes[i].TradeSeq) + } + + if trade.TradeID != getTradesRes[i].TradeID { + t.Errorf("Expected TradeID %s, actual %s", trade.TradeID, getTradesRes[i].TradeID) + } + + if trade.Amount != getTradesRes[i].Amount { + t.Errorf("Expected Amount %f, actual %f", trade.Amount, getTradesRes[i].Amount) + } + + if trade.Price != getTradesRes[i].Price { + t.Errorf("Expected Price %f, actual %f", trade.Price, getTradesRes[i].Price) + } + } + +} + +var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + +func randSeq(n int) string { + b := make([]rune, n) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return string(b) +} + +func TestClient_GetOrderByLabel(t *testing.T) { + client := newClient() + orderLabel := "TestClient_GetOrderByLabel" + randSeq(6) + params := &models.BuyParams{ + InstrumentName: "BTC-PERPETUAL", + Amount: 10, + Price: 20000.0, + Type: "limit", + Label: orderLabel, + } + newOrder, err := client.Buy(params) + if err != nil { + t.Fatal(err) + } + + fetchedOrders, err := client.GetOrderStateByLabel(&models.GetOrderStateByLabelParams{Label: orderLabel, Currency: "BTC"}) + if err != nil { + t.Error(err) + } else { + if len(fetchedOrders) == 0 { + t.Error("Count of fetchedOrders is equal to 0.") + } else { + lastOrder := fetchedOrders[len(fetchedOrders)-1] + if lastOrder.OrderID != newOrder.Order.OrderID { + t.Errorf("fetchedOrder OrderID != new OrderID, %s <> %s", lastOrder.OrderID, newOrder.Order.OrderID) + } + } + } + + cancelResult, err := client.CancelByLabel(&models.CancelByLabelParams{Label: orderLabel, Currency: "BTC"}) + if err != nil { + t.Fatal(err, cancelResult) + } +} + func TestJsonOmitempty(t *testing.T) { params := &models.BuyParams{ InstrumentName: "BTC-PERPETUAL", diff --git a/models/cancel_by_label.go b/models/cancel_by_label.go new file mode 100644 index 0000000..09d3b44 --- /dev/null +++ b/models/cancel_by_label.go @@ -0,0 +1,6 @@ +package models + +type CancelByLabelParams struct { + Label string `json:"label"` + Currency string `json:"currency,omitempty"` +} diff --git a/models/get_order_state_by_label.go b/models/get_order_state_by_label.go new file mode 100644 index 0000000..6a9271b --- /dev/null +++ b/models/get_order_state_by_label.go @@ -0,0 +1,6 @@ +package models + +type GetOrderStateByLabelParams struct { + Currency string `json:"currency"` + Label string `json:"label"` +} diff --git a/models/instrument.go b/models/instrument.go index 09712e0..327c02d 100644 --- a/models/instrument.go +++ b/models/instrument.go @@ -14,4 +14,7 @@ type Instrument struct { CreationTimestamp int64 `json:"creation_timestamp"` ContractSize float64 `json:"contract_size"` BaseCurrency string `json:"base_currency"` + CounterCurrency string `json:"counter_currency"` + InstrumentType string `json:"instrument_type"` + SettlementCurrency string `json:"settlement_currency"` } diff --git a/models/user_trade.go b/models/user_trade.go index f2054c7..5eb9ef0 100644 --- a/models/user_trade.go +++ b/models/user_trade.go @@ -18,4 +18,5 @@ type UserTrade struct { Fee float64 `json:"fee"` Direction string `json:"direction"` Amount float64 `json:"amount"` + Label string `json:"label"` }