Merge pull request #15 from wuhewuhe/master

tag 1.0.0
This commit is contained in:
CommaHunger 2023-11-06 17:29:52 +01:00 committed by GitHub
commit 8130843062
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 389 additions and 31 deletions

115
README.md
View File

@ -32,13 +32,126 @@ Your contributions are most welcome!
bybit-go-api is under active development with the latest features and updates from Bybit's API implemented promptly. The module utilizes minimal external libraries to provide a lightweight and efficient experience. If you've made enhancements or fixed bugs, please submit a pull request. bybit-go-api is under active development with the latest features and updates from Bybit's API implemented promptly. The module utilizes minimal external libraries to provide a lightweight and efficient experience. If you've made enhancements or fixed bugs, please submit a pull request.
## Installation ## Installation
Ensure you have go 1.21.0 or higher. You can include bybit-go-api in your project using Maven or Gradle. Ensure you have go 1.21.0 or higher. And use dependencies as below
```go
require (
github.com/google/uuid v1.4.0
github.com/gorilla/websocket v1.5.1
github.com/stretchr/testify v1.8.4
)
```
## Usage ## Usage
Note: Replace placeholders (like YOUR_API_KEY, links, or other details) with the actual information. You can also customize this template to better fit the actual state and details of your Java API. Note: Replace placeholders (like YOUR_API_KEY, links, or other details) with the actual information. You can also customize this template to better fit the actual state and details of your Java API.
### Rest API ### Rest API
- Place an order by Map
```go
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "linear", "symbol": "BTCUSDT", "side": "Buy", "positionIdx": 0, "orderType": "Limit", "qty": "0.001", "price": "10000", "timeInForce": "GTC"}
orderResult, err := client.NewTradeService(params).PlaceOrder(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(orderResult))
```
- Place an order by Trade Class
```go
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
orderResult, err := client.NewPlaceOrderService("linear", "XRPUSDT", "Buy", "Market", "10").Do(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(orderResult))
```
- Place batch order
```go
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "option",
"request": []map[string]interface{}{
{
"category": "option",
"symbol": "BTC-10FEB23-24000-C",
"orderType": "Limit",
"side": "Buy",
"qty": "0.1",
"price": "5",
"orderIv": "0.1",
"timeInForce": "GTC",
"orderLinkId": "9b381bb1-401",
"mmp": false,
"reduceOnly": false,
},
{
"category": "option",
"symbol": "BTC-10FEB23-24000-C",
"orderType": "Limit",
"side": "Buy",
"qty": "0.1",
"price": "5",
"orderIv": "0.1",
"timeInForce": "GTC",
"orderLinkId": "82ee86dd-001",
"mmp": false,
"reduceOnly": false,
},
},
}
orderResult, err := client.NewTradeService(params).PlaceBatchOrder(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(orderResult))
```
- Get Position
```go
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "linear", "settleCoin": "USDT", "limit": 10}
orderResult, err := client.NewPositionService(params).GetPositionList(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(orderResult))
```
- Get Transaction Log
```go
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"accountType": "UNIFIED", "category": "linear"}
accountResult, err := client.NewAccountService(params).GetTransactionLog(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(accountResult))
```
### Websocket public channel ### Websocket public channel
- Order book Subscribe
```go
ws := bybit.NewBybitPublicWebSocket("wss://stream.bybit.com/v5/public/spot", func(message string) error {
fmt.Println("Received:", message)
return nil
})
_ = ws.Connect([]string{"orderbook.1.BTCUSDT"})
select {}
```
### Websocket private channel ### Websocket private channel
```go
ws := bybit.NewBybitPrivateWebSocket("wss://stream-testnet.bybit.com/v5/private", "YOUR_API_KEY", "YOUR_API_SECRET", func(message string) error {
fmt.Println("Received:", message)
return nil
})
_ = ws.Connect([]string{"order"})
select {}
```
## Contact ## Contact
For support, join our Bybit API community on [Telegram](https://t.me/Bybitapi). For support, join our Bybit API community on [Telegram](https://t.me/Bybitapi).

View File

@ -64,6 +64,11 @@ func (c *Client) debug(format string, v ...interface{}) {
} }
} }
// FormatTimestamp formats a time into Unix timestamp in milliseconds, as requested by Binance.
func FormatTimestamp(t time.Time) int64 {
return t.UnixNano() / int64(time.Millisecond)
}
func GetCurrentTime() int64 { func GetCurrentTime() int64 {
now := time.Now() now := time.Now()
unixNano := now.UnixNano() unixNano := now.UnixNano()

150
bybit_api_client_test.go Normal file
View File

@ -0,0 +1,150 @@
package bybit_connector
import (
"bytes"
"context"
"io"
"net/http"
"net/url"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
type baseTestSuite struct {
suite.Suite
client *mockedClient
apiKey string
apiSecret string
baseURL string
}
func (s *baseTestSuite) r() *require.Assertions {
return s.Require()
}
func (s *baseTestSuite) SetupTest() {
s.apiKey = "dummyAPIKey"
s.apiSecret = "dummyApiSecret"
s.baseURL = "https://dummyapi.com"
s.client = newMockedClient(s.apiKey, s.apiSecret, s.baseURL)
}
func (s *baseTestSuite) mockDo(data []byte, err error, statusCode ...int) {
s.client.Client.do = s.client.do
code := http.StatusOK
if len(statusCode) > 0 {
code = statusCode[0]
}
s.client.On("do", anyHTTPRequest()).Return(newHTTPResponse(data, code), err)
}
func (s *baseTestSuite) assertDo() {
s.client.AssertCalled(s.T(), "do", anyHTTPRequest())
}
func (s *baseTestSuite) assertReq(f func(r *request)) {
s.client.assertReq = f
}
func (s *baseTestSuite) assertRequestEqual(e, a *request) {
s.assertURLValuesEqual(e.query, a.query)
}
func (s *baseTestSuite) assertURLValuesEqual(e, a url.Values) {
var eKeys, aKeys []string
for k := range e {
eKeys = append(eKeys, k)
}
for k := range a {
aKeys = append(aKeys, k)
}
r := s.r()
r.Len(aKeys, len(eKeys))
for k := range a {
switch k {
case timestampKey, signatureKey:
r.NotEmpty(a.Get(k))
continue
}
r.Equal(e[k], a[k], k)
}
}
func anythingOfType(t string) mock.AnythingOfTypeArgument {
return mock.AnythingOfType(t)
}
func newContext() context.Context {
return context.Background()
}
func anyHTTPRequest() mock.AnythingOfTypeArgument {
return anythingOfType("*http.Request")
}
func newHTTPResponse(data []byte, statusCode int) *http.Response {
return &http.Response{
Body: io.NopCloser(bytes.NewBuffer(data)),
StatusCode: statusCode,
}
}
func newRequest() *request {
r := &request{
query: url.Values{},
}
return r
}
func newSignedRequest() *request {
return newRequest().setParams(params{
timestampKey: "",
signatureKey: "",
apiRequestKey: "",
recvWindowKey: "5000",
signTypeKey: "2",
})
}
type assertReqFunc func(r *request)
type mockedClient struct {
mock.Mock
*Client
assertReq assertReqFunc
}
func newMockedClient(apiKey, apiSecret, baseURL string) *mockedClient {
m := new(mockedClient)
m.Client = NewBybitHttpClient(apiKey, apiSecret, WithBaseURL(baseURL))
return m
}
func (m *mockedClient) do(req *http.Request) (*http.Response, error) {
if m.assertReq != nil {
r := newRequest()
r.query = req.URL.Query()
if req.Body != nil && req.ContentLength > 0 {
bs := make([]byte, req.ContentLength)
_, err := req.Body.Read(bs)
if err != nil && err != io.EOF {
return nil, err // Handle read error
}
_ = req.Body.Close() // Close the body if we have read from it
r.body = bytes.NewBuffer(bs)
}
m.assertReq(r)
}
args := m.Called(req)
return args.Get(0).(*http.Response), args.Error(1)
}
func TestFormatTimestamp(t *testing.T) {
tm, _ := time.Parse("2006-01-02 15:04:05", "2018-06-01 01:01:01")
assert.Equal(t, int64(1527814861000), FormatTimestamp(tm))
}

View File

@ -11,7 +11,7 @@ func main() {
} }
func PlaceBatchTrade() { func PlaceBatchTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "option", params := map[string]interface{}{"category": "option",
"request": []map[string]interface{}{ "request": []map[string]interface{}{
{ {

View File

@ -11,7 +11,7 @@ func main() {
} }
func PlaceOrder() { func PlaceOrder() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
orderResult, err := client.NewPlaceOrderService("linear", "XRPUSDT", "Buy", "Market", "10").Do(context.Background()) orderResult, err := client.NewPlaceOrderService("linear", "XRPUSDT", "Buy", "Market", "10").Do(context.Background())
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)

View File

@ -11,7 +11,7 @@ func main() {
} }
func PlaceTrade() { func PlaceTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "linear", "symbol": "BTCUSDT", "side": "Buy", "positionIdx": 0, "orderType": "Limit", "qty": "0.001", "price": "10000", "timeInForce": "GTC"} params := map[string]interface{}{"category": "linear", "symbol": "BTCUSDT", "side": "Buy", "positionIdx": 0, "orderType": "Limit", "qty": "0.001", "price": "10000", "timeInForce": "GTC"}
orderResult, err := client.NewTradeService(params).PlaceOrder(context.Background()) orderResult, err := client.NewTradeService(params).PlaceOrder(context.Background())
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ func main() {
} }
func PlaceTrade() { func PlaceTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"accountType": "UNIFIED", "category": "linear"} params := map[string]interface{}{"accountType": "UNIFIED", "category": "linear"}
accountResult, err := client.NewAccountService(params).GetTransactionLog(context.Background()) accountResult, err := client.NewAccountService(params).GetTransactionLog(context.Background())
if err != nil { if err != nil {

View File

@ -1,7 +0,0 @@
package main
import "fmt"
func main() {
fmt.Println("hello world")
}

View File

@ -11,7 +11,7 @@ func main() {
} }
func AssetInfo() { func AssetInfo() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"accountType": "spot"} params := map[string]interface{}{"accountType": "spot"}
assetResult, err := client.NewAssetService(params).GetAssetInfo(context.Background()) assetResult, err := client.NewAssetService(params).GetAssetInfo(context.Background())
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ func main() {
} }
func GetCoinInfo() { func GetCoinInfo() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"coin": "USDT"} params := map[string]interface{}{"coin": "USDT"}
assetResult, err := client.NewAssetService(params).GetCoinInfo(context.Background()) assetResult, err := client.NewAssetService(params).GetCoinInfo(context.Background())
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ func main() {
} }
func PlaceTrade() { func PlaceTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{} params := map[string]interface{}{}
orderResult, err := client.NewBrokerService(params).GetBrokerEarning(context.Background()) orderResult, err := client.NewBrokerService(params).GetBrokerEarning(context.Background())
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ func main() {
} }
func PlaceTrade() { func PlaceTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"coin": "USDT"} params := map[string]interface{}{"coin": "USDT"}
orderResult, err := client.NewLendingService(params).GetC2cLendingCoinInfo(context.Background()) orderResult, err := client.NewLendingService(params).GetC2cLendingCoinInfo(context.Background())
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ func main() {
} }
func PlaceTrade() { func PlaceTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "linear", "settleCoin": "USDT", "limit": 10} params := map[string]interface{}{"category": "linear", "settleCoin": "USDT", "limit": 10}
orderResult, err := client.NewPositionService(params).GetPositionList(context.Background()) orderResult, err := client.NewPositionService(params).GetPositionList(context.Background())
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ func main() {
} }
func SwitchPositionMode() { func SwitchPositionMode() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "linear", "coin": "USDT", "mode": 3} params := map[string]interface{}{"category": "linear", "coin": "USDT", "mode": 3}
orderResult, err := client.NewPositionService(params).SwitchPositionMode(context.Background()) orderResult, err := client.NewPositionService(params).SwitchPositionMode(context.Background())
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ func main() {
} }
func PlaceTrade() { func PlaceTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "linear", "settleCoin": "USDT", "limit": 10} params := map[string]interface{}{"category": "linear", "settleCoin": "USDT", "limit": 10}
orderResult, err := client.NewPreUpgradeService(params).GetPreUpgradeOrderHistory(context.Background()) orderResult, err := client.NewPreUpgradeService(params).GetPreUpgradeOrderHistory(context.Background())
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ func main() {
} }
func PlaceTrade() { func PlaceTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"ltCoin": "BTC3L"} params := map[string]interface{}{"ltCoin": "BTC3L"}
leverageTokenResult, err := client.NewSpotLeverageService(params).GetLeverageTokenInfo(context.Background()) leverageTokenResult, err := client.NewSpotLeverageService(params).GetLeverageTokenInfo(context.Background())
if err != nil { if err != nil {

View File

@ -11,7 +11,7 @@ func main() {
} }
func SpotMarginData() { func SpotMarginData() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"ltCoin": "BTC3L"} params := map[string]interface{}{"ltCoin": "BTC3L"}
leverageTokenResult, err := client.NewSpotMarginDataService(params, true).GetSpotMarginData(context.Background()) leverageTokenResult, err := client.NewSpotMarginDataService(params, true).GetSpotMarginData(context.Background())
if err != nil { if err != nil {

View File

@ -11,8 +11,8 @@ func main() {
} }
func PlaceTrade() { func PlaceTrade() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET)) client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"username": "wuhe06112023Vic", "memberType": 1} params := map[string]interface{}{"username": "06112023Victor", "memberType": 1}
userResult, err := client.NewUserService(params).CreateSubMember(context.Background()) userResult, err := client.NewUserService(params).CreateSubMember(context.Background())
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)

View File

@ -6,11 +6,10 @@ import (
) )
func main() { func main() {
ws := bybit.NewBybitPrivateWebSocket("wss://stream-testnet.bybit.com/v5/private", "8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", func(message string) error { ws := bybit.NewBybitPrivateWebSocket("wss://stream-testnet.bybit.com/v5/private", "YOUR_API_KEY", "YOUR_API_SECRET", func(message string) error {
fmt.Println("Received:", message) fmt.Println("Received:", message)
return nil return nil
}) })
// Connect and subscribe to the desired topic
_ = ws.Connect([]string{"order"}) _ = ws.Connect([]string{"order"})
select {} select {}
} }

View File

@ -6,12 +6,10 @@ import (
) )
func main() { func main() {
// Create a public WebSocket client
ws := bybit.NewBybitPublicWebSocket("wss://stream.bybit.com/v5/public/spot", func(message string) error { ws := bybit.NewBybitPublicWebSocket("wss://stream.bybit.com/v5/public/spot", func(message string) error {
fmt.Println("Received:", message) fmt.Println("Received:", message)
return nil return nil
}) })
// Connect and subscribe to the desired topic
_ = ws.Connect([]string{"orderbook.1.BTCUSDT"}) _ = ws.Connect([]string{"orderbook.1.BTCUSDT"})
select {} select {}
} }

12
go.mod
View File

@ -3,7 +3,15 @@ module github.com/wuhewuhe/bybit.go.api
go 1.21 go 1.21
require ( require (
github.com/bitly/go-simplejson v0.5.1
github.com/google/uuid v1.4.0 github.com/google/uuid v1.4.0
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.1
github.com/stretchr/testify v1.8.4
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.1 // indirect
golang.org/x/net v0.17.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
) )

27
go.sum
View File

@ -1,7 +1,30 @@
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/bitly/go-simplejson v0.5.1/go.mod h1:YOPVLzCfwK14b4Sff3oP1AmGhI9T9Vsg84etUnlyp+Q= github.com/bitly/go-simplejson v0.5.1/go.mod h1:YOPVLzCfwK14b4Sff3oP1AmGhI9T9Vsg84etUnlyp+Q=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0=
github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

69
market_test.go Normal file
View File

@ -0,0 +1,69 @@
package bybit_connector
import (
"github.com/stretchr/testify/suite"
"github.com/wuhewuhe/bybit.go.api/models"
"testing"
)
type marketTestSuite struct {
baseTestSuite
}
func TestMarket(t *testing.T) {
suite.Run(t, new(marketTestSuite))
}
func (s *marketTestSuite) TestServerTime() {
data := []byte(`{
"retCode": 0,
"retMsg": "OK",
"result": {
"timeSecond": "1699287551",
"timeNano": "1699287551919622633"
},
"retExtInfo": {},
"time": 1699287551919
}`)
s.mockDo(data, nil)
defer s.assertDo()
s.assertReq(func(r *request) {
e := newRequest()
s.assertRequestEqual(e, r)
})
serverTime, err := s.client.NewMarketInfoServiceNoParams().GetServerTime(newContext())
e1 := &models.ServerTimeResult{
TimeSecond: "1699287551",
TimeNano: "1699287551919622633",
}
s.r().NoError(err)
s.assertServerTimeEqual(e1, serverTime)
}
func (s *marketTestSuite) assertServerTimeEqual(expected *models.ServerTimeResult, actual *ServerResponse) {
// Assert that the actual result is not nil and is a map
r := s.r()
actualResult, ok := actual.Result.(map[string]interface{})
if !ok {
r.FailNow("Actual result is not a map", "Actual Result: %#v", actual.Result)
return
}
// Cast the map to the expected struct type
var actualStruct models.ServerTimeResult
timeSecond, okSecond := actualResult["timeSecond"].(string)
timeNano, okNano := actualResult["timeNano"].(string)
if !okSecond || !okNano {
r.FailNow("Failed to cast actual result fields to string", "Actual Result: %#v", actual.Result)
return
}
actualStruct.TimeSecond = timeSecond
actualStruct.TimeNano = timeNano
// Compare the fields
r.Equal(expected.TimeSecond, actualStruct.TimeSecond, "TimeSecond field is not equal")
r.Equal(expected.TimeNano, actualStruct.TimeNano, "TimeNano field is not equal")
}