Compare commits

..

No commits in common. "main" and "v1.0.0" have entirely different histories.
main ... v1.0.0

51 changed files with 984 additions and 3018 deletions

28
.github/workflows/go.yml vendored Normal file
View File

@ -0,0 +1,28 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
name: Go
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.20'
- name: Build
run: go build -v ./...
- name: Test
run: go test -v ./...

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

9
.idea/bybit.go.api.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/bybit.go.api.iml" filepath="$PROJECT_DIR$/.idea/bybit.go.api.iml" />
</modules>
</component>
</project>

7
.idea/vcs.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -7,6 +7,7 @@
- [Usage](#usage) - [Usage](#usage)
- [Contact](#contact) - [Contact](#contact)
- [Contributors](#contributors) - [Contributors](#contributors)
- [Donations](#donations)
## About ## About
The Official Go Lang API connector for Bybit's HTTP and WebSocket APIs. The Official Go Lang API connector for Bybit's HTTP and WebSocket APIs.
@ -23,7 +24,7 @@ Dive into a plethora of functionalities:
bybit-go-api provides an official, robust, and high-performance go connector to Bybit's trading APIs. bybit-go-api provides an official, robust, and high-performance go connector to Bybit's trading APIs.
Initially conceptualized by go developer Victor, this module is now maintained by Bybit's in-house go experts. Initially conceptualized by esteemed go developer Victor, this module is now maintained by Bybit's in-house go experts.
Your contributions are most welcome! Your contributions are most welcome!
@ -40,9 +41,6 @@ require (
) )
``` ```
To import my package you need just to put the link to your go mode file
**github.com/wuhewuhe/bybit.go.api**
## 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
@ -176,3 +174,6 @@ List of other contributors
</td> </td>
</tr> </tr>
</table> </table>
## Donations
Your donations keep our development active and our community growing. Donate USDT to our [ERC20 Wallet Address](0x238bbb45af1254e2fd76564c9b56042c452f3d6e).

View File

@ -2,9 +2,9 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
) )
type AccountClient struct { type AccountClient struct {
@ -180,24 +180,6 @@ func (s *AccountClient) GetMMPState(ctx context.Context, opts ...RequestOption)
return res, nil return res, nil
} }
func (s *AccountClient) SetSpotHedgeMode(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
r := &request{
method: http.MethodGet,
endpoint: "/v5/account/set-hedging-mode",
secType: secTypeSigned,
}
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *AccountClient) UpgradeToUTA(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AccountClient) UpgradeToUTA(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
r := &request{ r := &request{
method: http.MethodPost, method: http.MethodPost,

View File

@ -2,9 +2,8 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
) )
type AssetClient struct { type AssetClient struct {
@ -18,7 +17,6 @@ func (s *AssetClient) GetAssetOrderRecord(ctx context.Context, opts ...RequestOp
endpoint: "/v5/asset/exchange/order-record", endpoint: "/v5/asset/exchange/order-record",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -37,7 +35,6 @@ func (s *AssetClient) GetAssetInfo(ctx context.Context, opts ...RequestOption) (
endpoint: "/v5/asset/transfer/query-asset-info", endpoint: "/v5/asset/transfer/query-asset-info",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -56,7 +53,6 @@ func (s *AssetClient) GetDeliveryRecord(ctx context.Context, opts ...RequestOpti
endpoint: "/v5/asset/delivery-record", endpoint: "/v5/asset/delivery-record",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -75,7 +71,6 @@ func (s *AssetClient) GetUsdcSettlement(ctx context.Context, opts ...RequestOpti
endpoint: "/v5/asset/settlement-record", endpoint: "/v5/asset/settlement-record",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -94,7 +89,6 @@ func (s *AssetClient) GetAllCoinsBalance(ctx context.Context, opts ...RequestOpt
endpoint: "/v5/asset/transfer/query-account-coins-balance", endpoint: "/v5/asset/transfer/query-account-coins-balance",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -108,15 +102,11 @@ func (s *AssetClient) GetAllCoinsBalance(ctx context.Context, opts ...RequestOpt
} }
func (s *AssetClient) GetSingleCoinsBalance(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AssetClient) GetSingleCoinsBalance(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{ r := &request{
method: http.MethodGet, method: http.MethodGet,
endpoint: "/v5/asset/transfer/query-account-coin-balance", endpoint: "/v5/asset/transfer/query-account-coin-balance",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -130,15 +120,11 @@ func (s *AssetClient) GetSingleCoinsBalance(ctx context.Context, opts ...Request
} }
func (s *AssetClient) GetTransferableCoin(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AssetClient) GetTransferableCoin(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{ r := &request{
method: http.MethodGet, method: http.MethodGet,
endpoint: "/v5/asset/transfer/query-transfer-coin-list", endpoint: "/v5/asset/transfer/query-transfer-coin-list",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -152,15 +138,11 @@ func (s *AssetClient) GetTransferableCoin(ctx context.Context, opts ...RequestOp
} }
func (s *AssetClient) CreateInternalTransfer(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AssetClient) CreateInternalTransfer(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{ r := &request{
method: http.MethodPost, method: http.MethodPost,
endpoint: "/v5/asset/transfer/inter-transfer", endpoint: "/v5/asset/transfer/inter-transfer",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -174,15 +156,11 @@ func (s *AssetClient) CreateInternalTransfer(ctx context.Context, opts ...Reques
} }
func (s *AssetClient) CreateUniversalTransfer(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AssetClient) CreateUniversalTransfer(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{ r := &request{
method: http.MethodPost, method: http.MethodPost,
endpoint: "/v5/asset/transfer/universal-transfer", endpoint: "/v5/asset/transfer/universal-transfer",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -196,15 +174,11 @@ func (s *AssetClient) CreateUniversalTransfer(ctx context.Context, opts ...Reque
} }
func (s *AssetClient) SetDepositAccount(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AssetClient) SetDepositAccount(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{ r := &request{
method: http.MethodPost, method: http.MethodPost,
endpoint: "/v5/asset/deposit/deposit-to-account", endpoint: "/v5/asset/deposit/deposit-to-account",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -218,15 +192,11 @@ func (s *AssetClient) SetDepositAccount(ctx context.Context, opts ...RequestOpti
} }
func (s *AssetClient) WithdrawAsset(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AssetClient) WithdrawAsset(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{ r := &request{
method: http.MethodPost, method: http.MethodPost,
endpoint: "/v5/asset/withdraw/create", endpoint: "/v5/asset/withdraw/create",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -240,15 +210,11 @@ func (s *AssetClient) WithdrawAsset(ctx context.Context, opts ...RequestOption)
} }
func (s *AssetClient) CancelWithdrawAsset(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AssetClient) CancelWithdrawAsset(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{ r := &request{
method: http.MethodPost, method: http.MethodPost,
endpoint: "/v5/asset/withdraw/cancel", endpoint: "/v5/asset/withdraw/cancel",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -262,15 +228,11 @@ func (s *AssetClient) CancelWithdrawAsset(ctx context.Context, opts ...RequestOp
} }
func (s *AssetClient) GetInternalTransfer(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AssetClient) GetInternalTransfer(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{ r := &request{
method: http.MethodGet, method: http.MethodGet,
endpoint: "/v5/asset/transfer/query-inter-transfer-list", endpoint: "/v5/asset/transfer/query-inter-transfer-list",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -289,7 +251,6 @@ func (s *AssetClient) GetUniversalTransfer(ctx context.Context, opts ...RequestO
endpoint: "/v5/asset/transfer/query-universal-transfer-list", endpoint: "/v5/asset/transfer/query-universal-transfer-list",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -308,7 +269,6 @@ func (s *AssetClient) GetSubUids(ctx context.Context, opts ...RequestOption) (re
endpoint: "/v5/asset/transfer/query-sub-member-list", endpoint: "/v5/asset/transfer/query-sub-member-list",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -327,7 +287,6 @@ func (s *AssetClient) GetAllowedDepositCoin(ctx context.Context, opts ...Request
endpoint: "/v5/asset/deposit/query-allowed-list", endpoint: "/v5/asset/deposit/query-allowed-list",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -346,7 +305,6 @@ func (s *AssetClient) GetDepositRecords(ctx context.Context, opts ...RequestOpti
endpoint: "/v5/asset/deposit/query-record", endpoint: "/v5/asset/deposit/query-record",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -365,7 +323,6 @@ func (s *AssetClient) GetSubDepositRecords(ctx context.Context, opts ...RequestO
endpoint: "/v5/asset/deposit/query-sub-member-record", endpoint: "/v5/asset/deposit/query-sub-member-record",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -384,7 +341,6 @@ func (s *AssetClient) GetInternalDepositRecords(ctx context.Context, opts ...Req
endpoint: "/v5/asset/deposit/query-internal-record", endpoint: "/v5/asset/deposit/query-internal-record",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -403,7 +359,6 @@ func (s *AssetClient) GetMasterDepositAddress(ctx context.Context, opts ...Reque
endpoint: "/v5/asset/deposit/query-address", endpoint: "/v5/asset/deposit/query-address",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -422,7 +377,6 @@ func (s *AssetClient) GetSubDepositAddress(ctx context.Context, opts ...RequestO
endpoint: "/v5/asset/deposit/query-sub-member-address", endpoint: "/v5/asset/deposit/query-sub-member-address",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -441,7 +395,6 @@ func (s *AssetClient) GetCoinInfo(ctx context.Context, opts ...RequestOption) (r
endpoint: "/v5/asset/coin/query-info", endpoint: "/v5/asset/coin/query-info",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -460,7 +413,6 @@ func (s *AssetClient) GetWithdrawalAmount(ctx context.Context, opts ...RequestOp
endpoint: "/v5/asset/withdraw/withdrawable-amount", endpoint: "/v5/asset/withdraw/withdrawable-amount",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -472,14 +424,12 @@ func (s *AssetClient) GetWithdrawalAmount(ctx context.Context, opts ...RequestOp
} }
return res, nil return res, nil
} }
func (s *AssetClient) GetWithdrawalRecords(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *AssetClient) GetWithdrawalRecords(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
r := &request{ r := &request{
method: http.MethodGet, method: http.MethodGet,
endpoint: "/v5/asset/withdraw/query-record", endpoint: "/v5/asset/withdraw/query-record",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -2,9 +2,9 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
) )
type BrokerServiceClient struct { type BrokerServiceClient struct {
@ -18,29 +18,7 @@ func (s *BrokerServiceClient) GetBrokerEarning(ctx context.Context, opts ...Requ
} }
r := &request{ r := &request{
method: http.MethodGet, method: http.MethodGet,
endpoint: "/v5/broker/earnings-info", endpoint: "/v5/broker/earning-record",
secType: secTypeSigned,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *BrokerServiceClient) GetBrokerAccountInfo(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/broker/account-info",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params) r.setParams(s.params)

View File

@ -6,21 +6,17 @@ import (
"crypto/hmac" "crypto/hmac"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"encoding/json"
"fmt" "fmt"
"github.com/wuhewuhe/bybit.go.api/handlers"
"io" "io"
"log" "log"
"net/http" "net/http"
"os" "os"
"strconv" "strconv"
"time" "time"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
"github.com/bitly/go-simplejson"
jsoniter "github.com/json-iterator/go"
) )
var json = jsoniter.ConfigCompatibleWithStandardLibrary
type ServerResponse struct { type ServerResponse struct {
RetCode int `json:"retCode"` RetCode int `json:"retCode"`
RetMsg string `json:"retMsg"` RetMsg string `json:"retMsg"`
@ -44,7 +40,6 @@ type doFunc func(req *http.Request) (*http.Response, error)
type ClientOption func(*Client) type ClientOption func(*Client)
// WithDebug print more details in debug mode
func WithDebug(debug bool) ClientOption { func WithDebug(debug bool) ClientOption {
return func(c *Client) { return func(c *Client) {
c.Debug = debug c.Debug = debug
@ -59,7 +54,7 @@ func WithBaseURL(baseURL string) ClientOption {
} }
func PrettyPrint(i interface{}) string { func PrettyPrint(i interface{}) string {
s, _ := json.MarshalIndent(i, "", " ") s, _ := json.MarshalIndent(i, "", "\t")
return string(s) return string(s)
} }
@ -81,14 +76,6 @@ func GetCurrentTime() int64 {
return timeStamp return timeStamp
} }
func newJSON(data []byte) (j *simplejson.Json, err error) {
j, err = simplejson.NewJson(data)
if err != nil {
return nil, err
}
return j, nil
}
// NewBybitHttpClient NewClient Create client function for initialising new Bybit client // NewBybitHttpClient NewClient Create client function for initialising new Bybit client
func NewBybitHttpClient(apiKey string, APISecret string, options ...ClientOption) *Client { func NewBybitHttpClient(apiKey string, APISecret string, options ...ClientOption) *Client {
c := &Client{ c := &Client{
@ -164,9 +151,6 @@ func (c *Client) parseRequest(r *request, opts ...RequestOption) (err error) {
func (c *Client) callAPI(ctx context.Context, r *request, opts ...RequestOption) (data []byte, err error) { func (c *Client) callAPI(ctx context.Context, r *request, opts ...RequestOption) (data []byte, err error) {
err = c.parseRequest(r, opts...) err = c.parseRequest(r, opts...)
if err != nil {
return nil, err
}
req, err := http.NewRequest(r.method, r.fullURL, r.body) req, err := http.NewRequest(r.method, r.fullURL, r.body)
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
@ -199,7 +183,9 @@ func (c *Client) callAPI(ctx context.Context, r *request, opts ...RequestOption)
c.debug("response status code: %d", res.StatusCode) c.debug("response status code: %d", res.StatusCode)
if res.StatusCode >= http.StatusBadRequest { if res.StatusCode >= http.StatusBadRequest {
apiErr := new(handlers.APIError) var (
apiErr = new(handlers.APIError)
)
e := json.Unmarshal(data, apiErr) e := json.Unmarshal(data, apiErr)
if e != nil { if e != nil {
c.debug("failed to unmarshal json: %s", e) c.debug("failed to unmarshal json: %s", e)
@ -209,79 +195,36 @@ func (c *Client) callAPI(ctx context.Context, r *request, opts ...RequestOption)
return data, nil return data, nil
} }
func (c *Client) NewInstrumentsInfoService() *InstrumentsInfoService { // NewMarketKlineService Market Endpoints
return &InstrumentsInfoService{c: c} func (c *Client) NewMarketKlineService(klineType, category, symbol, interval string) *Klines {
return &Klines{
c: c,
category: category,
symbol: symbol,
interval: interval,
klineType: klineType,
}
} }
// NewMarketKlineService Market Kline Endpoints func (c *Client) NewMarketKLinesService(klineType string, params map[string]interface{}) *MarketClient {
func (c *Client) NewMarketKlineService() *MarketKlinesService { return &MarketClient{
return &MarketKlinesService{c: c} c: c,
klineType: klineType,
params: params,
}
} }
// NewMarketMarkPriceKlineService Market Mark Price Kline Endpoints func (c *Client) NewMarketInfoServiceNoParams() *MarketClient {
func (c *Client) NewMarketMarkPriceKlineService() *MarketMarkPriceKlineService { return &MarketClient{
return &MarketMarkPriceKlineService{c: c} c: c,
}
} }
// NewMarketIndexPriceKlineService Market Index Price Kline Endpoints func (c *Client) NewMarketInfoService(params map[string]interface{}) *MarketClient {
func (c *Client) NewMarketIndexPriceKlineService() *MarketIndexPriceKlineService { return &MarketClient{
return &MarketIndexPriceKlineService{c: c} c: c,
} params: params,
}
// NewMarketPremiumIndexPriceKlineService Market Premium Index Price Kline Endpoints
func (c *Client) NewMarketPremiumIndexPriceKlineService() *MarketPremiumIndexPriceKlineService {
return &MarketPremiumIndexPriceKlineService{c: c}
}
func (c *Client) NewOrderBookService() *MarketOrderBookService {
return &MarketOrderBookService{c: c}
}
func (c *Client) NewTickersService() *MarketTickersService {
return &MarketTickersService{c: c}
}
func (c *Client) NewFundingTatesService() *MarketFundingRatesService {
return &MarketFundingRatesService{c: c}
}
func (c *Client) NewGetPublicRecentTradesService() *GetPublicRecentTradesService {
return &GetPublicRecentTradesService{c: c}
}
// GetOpenInterestsServicdde
func (c *Client) NewGetOpenInterestsService() *GetOpenInterestsService {
return &GetOpenInterestsService{c: c}
}
// GetHistoricalVolatilityService
func (c *Client) NewGetHistoricalVolatilityService() *GetHistoricalVolatilityService {
return &GetHistoricalVolatilityService{c: c}
}
// GetInsuranceInfoService
func (c *Client) NewGetInsuranceInfoService() *GetInsuranceInfoService {
return &GetInsuranceInfoService{c: c}
}
// GetRiskLimitService
func (c *Client) NewGetRiskLimitService() *GetRiskLimitService {
return &GetRiskLimitService{c: c}
}
// GetDeliveryPriceService
func (c *Client) NewGetDeliveryPriceService() *GetDeliveryPriceService {
return &GetDeliveryPriceService{c: c}
}
// GetMarketLSRatioService
func (c *Client) NewGetMarketLSRatioService() *GetMarketLSRatioService {
return &GetMarketLSRatioService{c: c}
}
// GetServerTimeService
func (c *Client) NewGetServerTimeService() *GetServerTimeService {
return &GetServerTimeService{c: c}
} }
// NewPlaceOrderService Trade Endpoints // NewPlaceOrderService Trade Endpoints
@ -308,6 +251,7 @@ func (c *Client) NewPositionService(params map[string]interface{}) *PositionClie
c: c, c: c,
params: params, params: params,
} }
} }
func (c *Client) NewPreUpgradeService(params map[string]interface{}) *PreUpgradeClient { func (c *Client) NewPreUpgradeService(params map[string]interface{}) *PreUpgradeClient {
@ -344,12 +288,6 @@ func (c *Client) NewUserService(params map[string]interface{}) *UserServiceClien
} }
} }
func (c *Client) NewUserServiceNoParams() *UserServiceClient {
return &UserServiceClient{
c: c,
}
}
func (c *Client) NewBrokerService(params map[string]interface{}) *BrokerServiceClient { func (c *Client) NewBrokerService(params map[string]interface{}) *BrokerServiceClient {
return &BrokerServiceClient{ return &BrokerServiceClient{
c: c, c: c,

View File

@ -1,34 +1,31 @@
package bybit_connector package bybit_connector
import ( import (
"context"
"crypto/hmac" "crypto/hmac"
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"errors" "encoding/json"
"fmt" "fmt"
"time"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"golang.org/x/sync/errgroup" "time"
) )
type MessageHandler func(message string) error type MessageHandler func(message string) error
func (b *WebSocket) handleIncomingMessages() error { func (b *WebSocket) handleIncomingMessages() {
for { for {
_, message, err := b.conn.ReadMessage() _, message, err := b.conn.ReadMessage()
if err != nil { if err != nil {
fmt.Println("Error reading:", err) fmt.Println("Error reading:", err)
return err return
} }
if b.onMessage != nil { if b.onMessage != nil {
err := b.onMessage(string(message)) err := b.onMessage(string(message))
if err != nil { if err != nil {
fmt.Println("Error handling message:", err) fmt.Println("Error handling message:", err)
return err return
} }
} }
} }
@ -43,66 +40,27 @@ type WebSocket struct {
url string url string
apiKey string apiKey string
apiSecret string apiSecret string
maxAliveTime string
pingInterval int
onMessage MessageHandler onMessage MessageHandler
ctx context.Context
cancel context.CancelFunc
} }
type WebsocketOption func(*WebSocket) func NewBybitPrivateWebSocket(url, apiKey, apiSecret string, handler MessageHandler) *WebSocket {
return &WebSocket{
func WithPingInterval(pingInterval int) WebsocketOption {
return func(c *WebSocket) {
c.pingInterval = pingInterval
}
}
func WithMaxAliveTime(maxAliveTime string) WebsocketOption {
return func(c *WebSocket) {
c.maxAliveTime = maxAliveTime
}
}
func NewBybitPrivateWebSocket(url, apiKey, apiSecret string, handler MessageHandler, options ...WebsocketOption) *WebSocket {
c := &WebSocket{
url: url, url: url,
apiKey: apiKey, apiKey: apiKey,
apiSecret: apiSecret, apiSecret: apiSecret,
maxAliveTime: "",
pingInterval: 20,
onMessage: handler, onMessage: handler,
} }
// Apply the provided options
for _, opt := range options {
opt(c)
}
return c
} }
func NewBybitPublicWebSocket(url string, pingInterval int, handler MessageHandler, options ...WebsocketOption) *WebSocket { func NewBybitPublicWebSocket(url string, handler MessageHandler) *WebSocket {
c := &WebSocket{ return &WebSocket{
url: url, url: url,
pingInterval: pingInterval, // default is 20 seconds
onMessage: handler, onMessage: handler,
} }
// Apply the provided options
for _, opt := range options {
opt(c)
}
return c
} }
func (b *WebSocket) Connect(args []string) error { func (b *WebSocket) Connect(args []string) error {
var err error var err error
wssUrl := b.url
if b.maxAliveTime != "" {
wssUrl += "?max_alive_time=" + b.maxAliveTime
}
b.conn, _, err = websocket.DefaultDialer.Dial(b.url, nil) b.conn, _, err = websocket.DefaultDialer.Dial(b.url, nil)
if err != nil { if err != nil {
return err return err
@ -114,49 +72,30 @@ func (b *WebSocket) Connect(args []string) error {
} }
} }
eg := errgroup.Group{} go b.handleIncomingMessages()
b.ctx, b.cancel = context.WithCancel(context.Background()) Ping(b)
eg.Go(b.Ping) return b.sendSubscription(args)
eg.Go(b.handleIncomingMessages)
if err := b.sendSubscription(args); err != nil {
return fmt.Errorf("failed to send subscription: %w", err)
}
if err := eg.Wait(); err != nil {
b.Disconnect()
return fmt.Errorf("failed to handle message: %w", err)
}
return nil
} }
var ErrPingFailed = errors.New("failed to send ping") func Ping(b *WebSocket) {
ticker := time.NewTicker(15 * time.Second)
func (b *WebSocket) Ping() error { go func() {
ticker := time.NewTicker(time.Duration(b.pingInterval) * time.Second)
defer ticker.Stop() // Ensure the ticker is stopped when this goroutine ends defer ticker.Stop() // Ensure the ticker is stopped when this goroutine ends
for { for {
select { select {
case <-ticker.C: // Wait until the ticker sends a signal case <-ticker.C: // Wait until the ticker sends a signal
if err := b.conn.WriteMessage(websocket.PingMessage, nil); err != nil { if err := b.conn.WriteMessage(websocket.PingMessage, nil); err != nil {
fmt.Println("Failed to send ping:", err) fmt.Println("Failed to send ping:", err)
return ErrPingFailed
}
case <-b.ctx.Done():
fmt.Println("Exit ping")
return nil
} }
} }
}
}()
} }
func (b *WebSocket) Disconnect() error { func (b *WebSocket) Disconnect() error {
b.cancel() return b.conn.Close()
err := b.conn.Close()
fmt.Println("WebSocket disconnected, err =", err)
return err
} }
func (b *WebSocket) Send(message string) error { func (b *WebSocket) Send(message string) error {
@ -184,7 +123,7 @@ func (b *WebSocket) sendAuth() error {
fmt.Println("signature generated : " + signature) fmt.Println("signature generated : " + signature)
authMessage := map[string]interface{}{ authMessage := map[string]interface{}{
"req_id": uuid.New(), "req_id": uuid.New(), // You would need to implement or find a package for generating GUID
"op": "auth", "op": "auth",
"args": []interface{}{b.apiKey, expires, signature}, "args": []interface{}{b.apiKey, expires, signature},
} }

View File

@ -2,7 +2,7 @@ package bybit_connector
const ( const (
Name = "bybit.api.go" Name = "bybit.api.go"
Version = "1.0.2" Version = "1.0.0"
// Https // Https
MAINNET = "https://api.bybit.com" MAINNET = "https://api.bybit.com"
MAINNET_BACKT = "https://api.bytick.com" MAINNET_BACKT = "https://api.bytick.com"

View File

@ -1,23 +0,0 @@
package main
import (
"context"
"fmt"
bybit "gitea.computernetthings.ru/yash/bybit.go.api"
)
func main() {
PlaceOrder()
}
func PlaceOrder() {
client := bybit.NewBybitHttpClient("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"fromAccountType": "UNIFIED", "toAccountType": "CONTRACT"}
response, err := client.NewAssetService(params).GetTransferableCoin(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(response))
}

View File

@ -3,8 +3,7 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
bybit "gitea.computernetthings.ru/yash/bybit.go.api"
) )
func main() { func main() {
@ -12,9 +11,8 @@ 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{}{ params := map[string]interface{}{"category": "option",
"category": "option",
"request": []map[string]interface{}{ "request": []map[string]interface{}{
{ {
"category": "option", "category": "option",

View File

@ -3,8 +3,7 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
bybit "gitea.computernetthings.ru/yash/bybit.go.api"
) )
func main() { func main() {
@ -12,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

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
PlaceTrade()
}
func PlaceTrade() {
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))
}

View File

@ -3,8 +3,7 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
bybit "gitea.computernetthings.ru/yash/bybit.go.api"
) )
func main() { func main() {
@ -12,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

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
AssetInfo()
}
func AssetInfo() {
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"accountType": "spot"}
assetResult, err := client.NewAssetService(params).GetAssetInfo(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(assetResult))
}

View File

@ -3,8 +3,7 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
bybit "gitea.computernetthings.ru/yash/bybit.go.api"
) )
func main() { func main() {
@ -12,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

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
PlaceTrade()
}
func PlaceTrade() {
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{}
orderResult, err := client.NewBrokerService(params).GetBrokerEarning(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(orderResult))
}

View File

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
PlaceTrade()
}
func PlaceTrade() {
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"coin": "USDT"}
orderResult, err := client.NewLendingService(params).GetC2cLendingCoinInfo(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(orderResult))
}

View File

@ -0,0 +1,25 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
InstrumentInfo()
}
func InstrumentInfo() {
client := bybit.NewBybitHttpClient("", "")
// NewServerTimeService
params := map[string]interface{}{"category": "linear", "symbol": "BTCUSDT", "status": "Trading"}
marketKline, err := client.NewMarketInfoService(params).GetInstrumentInfo(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(marketKline))
}

View File

@ -0,0 +1,25 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
IndexKline()
}
func IndexKline() {
client := bybit.NewBybitHttpClient("", "")
// NewServerTimeService
params := map[string]interface{}{"category": "linear", "symbol": "BTCUSDT", "interval": "1", "Limit": 2}
marketKline, err := client.NewMarketKLinesService("index-price-kline", params).GetMarketKline(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(marketKline))
}

View File

@ -0,0 +1,24 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
MarketKline()
}
func MarketKline() {
client := bybit.NewBybitHttpClient("", "")
// NewServerTimeService
marketKline, err := client.NewMarketKlineService("premium-index-price-kline", "linear", "BTCUSDT", "1").Limit(10).Do(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(marketKline))
}

View File

@ -0,0 +1,24 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
ServerTime()
}
func ServerTime() {
client := bybit.NewBybitHttpClient("", "")
// NewServerTimeService
serverTime, err := client.NewMarketInfoServiceNoParams().GetServerTime(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(serverTime))
}

View File

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
PlaceTrade()
}
func PlaceTrade() {
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))
}

View File

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
SwitchPositionMode()
}
func SwitchPositionMode() {
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"category": "linear", "coin": "USDT", "mode": 3}
orderResult, err := client.NewPositionService(params).SwitchPositionMode(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(orderResult))
}

View File

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
PlaceTrade()
}
func PlaceTrade() {
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.NewPreUpgradeService(params).GetPreUpgradeOrderHistory(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(orderResult))
}

View File

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
PlaceTrade()
}
func PlaceTrade() {
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"ltCoin": "BTC3L"}
leverageTokenResult, err := client.NewSpotLeverageService(params).GetLeverageTokenInfo(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(leverageTokenResult))
}

View File

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
SpotMarginData()
}
func SpotMarginData() {
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"ltCoin": "BTC3L"}
leverageTokenResult, err := client.NewSpotMarginDataService(params, true).GetSpotMarginData(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(leverageTokenResult))
}

View File

@ -0,0 +1,22 @@
package main
import (
"context"
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
PlaceTrade()
}
func PlaceTrade() {
client := bybit.NewBybitHttpClient("YOUR_API_KEY", "YOUR_API_SECRET", bybit.WithBaseURL(bybit.TESTNET))
params := map[string]interface{}{"username": "06112023Victor", "memberType": 1}
userResult, err := client.NewUserService(params).CreateSubMember(context.Background())
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bybit.PrettyPrint(userResult))
}

View File

@ -0,0 +1,15 @@
package main
import (
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
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 {}
}

View File

@ -0,0 +1,15 @@
package main
import (
"fmt"
bybit "github.com/wuhewuhe/bybit.go.api"
)
func main() {
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 {}
}

11
go.mod
View File

@ -1,22 +1,17 @@
module gitea.computernetthings.ru/yash/bybit.go.api 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.5.0
github.com/gorilla/websocket v1.5.1 github.com/gorilla/websocket v1.5.1
github.com/json-iterator/go v1.1.12
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
golang.org/x/sync v0.7.0
) )
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.1 // indirect github.com/stretchr/objx v0.5.1 // indirect
golang.org/x/net v0.19.0 // indirect golang.org/x/net v0.17.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

23
go.sum
View File

@ -1,37 +1,28 @@
github.com/bitly/go-simplejson v0.5.1 h1:xgwPbetQScXt1gh9BmoJ6j9JMr3TElvuIyjR8pgdoow=
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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.5.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/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/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.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.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.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= 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/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.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.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 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/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.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -2,9 +2,9 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
) )
type LendingServiceClient struct { type LendingServiceClient struct {

296
market.go Normal file
View File

@ -0,0 +1,296 @@
package bybit_connector
import (
"context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http"
)
type MarketClient struct {
c *Client
klineType string
params map[string]interface{}
}
func (s *MarketClient) GetServerTime(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/time",
secType: secTypeNone,
}
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetMarketKline(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/" + s.klineType,
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetInstrumentInfo(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/instruments-info",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetOrderBookInfo(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/orderbook",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetMarketTickers(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/tickers",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetFundingRates(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/tickers",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetPublicRecentTrades(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/recent-trade",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetOpenInterests(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/open-interest",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetHistoricalVolatility(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/historical-volatility",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetInsuranceInfo(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/insurance",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetRiskLimit(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/risk-limit",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetDeliveryPrice(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/delivery-price",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}
func (s *MarketClient) GetMarketLSRatio(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/account-ratio",
secType: secTypeNone,
}
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}

67
market_klines.go Normal file
View File

@ -0,0 +1,67 @@
package bybit_connector
import (
"context"
"encoding/json"
"net/http"
)
// Klines Market Kline (GET /v5/market/kline)
type Klines struct {
c *Client
klineType string
category string
symbol string
interval string
limit *int
start *uint64
end *uint64
}
// Limit set limit
func (s *Klines) Limit(limit int) *Klines {
s.limit = &limit
return s
}
// Start set startTime
func (s *Klines) Start(startTime uint64) *Klines {
s.start = &startTime
return s
}
// End set endTime
func (s *Klines) End(endTime uint64) *Klines {
s.end = &endTime
return s
}
func (s *Klines) Do(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
r := &request{
method: http.MethodGet,
endpoint: "/v5/market/" + s.klineType,
secType: secTypeNone,
}
r.setParam("category", s.category)
r.setParam("symbol", s.symbol)
r.setParam("interval", s.interval)
if s.limit != nil {
r.setParam("limit", *s.limit)
}
if s.start != nil {
r.setParam("start", *s.start)
}
if s.end != nil {
r.setParam("end", *s.end)
}
data, err := s.c.callAPI(ctx, r, opts...)
if err != nil {
return nil, err
}
res = new(ServerResponse)
err = json.Unmarshal(data, res)
if err != nil {
return nil, err
}
return res, nil
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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")
}

View File

@ -1,52 +0,0 @@
package models
type Category string
const (
CategorySpot Category = "spot"
CategoryLinear Category = "linear" //Unified Account: USDT perpetual, and USDC contract, including USDC perp, USDC futures; Classic Account: USDT perp
CategoryInverse Category = "inverse" // Inverse contract, including Inverse perp, Inverse futures
CategoryOption Category = "option"
)
type OrderStatus string
const (
OrderStatusCreated OrderStatus = "Created" //order has been accepted by the system but not yet put through the matching engine
OrderStatusNew OrderStatus = "New" //order has been placed successfully
OrderStatusRejected OrderStatus = "Rejected"
OrderStatusPartiallyFilled OrderStatus = "PartiallyFilled"
OrderStatusPartiallyFilledCanceled OrderStatus = "PartiallyFilledCanceled" //Only spot has this order status
OrderStatusFilled OrderStatus = "Filled"
OrderStatusCancelled OrderStatus = "Cancelled" //In derivatives, orders with this status may have an executed qty
OrderStatusUntriggered OrderStatus = "Untriggered"
OrderStatusTriggered OrderStatus = "Triggered"
OrderStatusDeactivated OrderStatus = "Deactivated" //UTA: Spot tp/sl order, conditional order, OCO order are cancelled before they are triggered
)
type TimeInForce string
const (
TimeInForceGTC TimeInForce = "GTC" //GoodTillCancel
TimeInForceIOC TimeInForce = "IOC" //ImmediateOrCancel
TimeInForceFOK TimeInForce = "FOK" //FillOrKill
TimeInForcePostOnly TimeInForce = "PostOnly"
)
type OrderType string
const (
OrderTypeMarket OrderType = "Market"
Limit OrderType = "Limit"
UNKNOWN OrderType = "UNKNOWN" //Is not a valid request parameter value. Is only used in some responses. Mainly, it is used when execType is Funding.
)
type SymbolStatus string
const (
SymbolStatusPreLaunch SymbolStatus = "PreLaunch"
SymbolStatusTrading SymbolStatus = "Trading"
SymbolStatusSettling SymbolStatus = "Settling"
SymbolStatusDelivering SymbolStatus = "Delivering"
SymbolStatusClosed SymbolStatus = "Closed"
)

View File

@ -16,55 +16,13 @@ type MarketKlineCandle struct {
} }
type MarketKlineResponse struct { type MarketKlineResponse struct {
Category Category `json:"category"` Category string `json:"category"`
Symbol string `json:"symbol"` Symbol string `json:"symbol"`
List []*MarketKlineCandle `json:"list"` List []MarketKlineCandle `json:"list"`
} }
type MarketMarkPriceKlineCandle struct { type InstrumentInfo struct {
StartTime string `json:"startTime"` Category string `json:"category"`
OpenPrice string `json:"openPrice"`
HighPrice string `json:"highPrice"`
LowPrice string `json:"lowPrice"`
ClosePrice string `json:"closePrice"`
}
type MarketMarkPriceKlineResponse struct {
Category Category `json:"category"`
Symbol string `json:"symbol"`
List []*MarketMarkPriceKlineCandle `json:"list"`
}
type MarketIndexPriceKlineCandle struct {
StartTime string `json:"startTime"`
OpenPrice string `json:"openPrice"`
HighPrice string `json:"highPrice"`
LowPrice string `json:"lowPrice"`
ClosePrice string `json:"closePrice"`
}
type MarketIndexPriceKlineResponse struct {
Category Category `json:"category"`
Symbol string `json:"symbol"`
List []*MarketIndexPriceKlineCandle `json:"list"`
}
type MarketPremiumIndexPriceKlineCandle struct {
StartTime string `json:"startTime"`
OpenPrice string `json:"openPrice"`
HighPrice string `json:"highPrice"`
LowPrice string `json:"lowPrice"`
ClosePrice string `json:"closePrice"`
}
type MarketPremiumIndexPriceKlineResponse struct {
Category Category `json:"category"`
Symbol string `json:"symbol"`
List []*MarketPremiumIndexPriceKlineCandle `json:"list"`
}
type InstrumentInfoResponse struct {
Category Category `json:"category"`
NextPageCursor string `json:"nextPageCursor"` NextPageCursor string `json:"nextPageCursor"`
List []Instrument `json:"list"` List []Instrument `json:"list"`
} }
@ -72,16 +30,13 @@ type InstrumentInfoResponse struct {
type Instrument struct { type Instrument struct {
Symbol string `json:"symbol"` Symbol string `json:"symbol"`
ContractType string `json:"contractType"` ContractType string `json:"contractType"`
OptionType string `json:"optionType"` Status string `json:"status"`
Innovation string `json:"innovation"`
Status SymbolStatus `json:"status"`
BaseCoin string `json:"baseCoin"` BaseCoin string `json:"baseCoin"`
QuoteCoin string `json:"quoteCoin"` QuoteCoin string `json:"quoteCoin"`
LaunchTime string `json:"launchTime"` LaunchTime string `json:"launchTime"`
DeliveryTime string `json:"deliveryTime"` DeliveryTime string `json:"deliveryTime"`
DeliveryFeeRate string `json:"deliveryFeeRate"` DeliveryFeeRate string `json:"deliveryFeeRate"`
PriceScale string `json:"priceScale"` PriceScale string `json:"priceScale"`
MarginTrading string `json:"marginTrading"`
LeverageFilter LeverageFilter `json:"leverageFilter"` LeverageFilter LeverageFilter `json:"leverageFilter"`
PriceFilter PriceFilter `json:"priceFilter"` PriceFilter PriceFilter `json:"priceFilter"`
LotSizeFilter LotSizeFilter `json:"lotSizeFilter"` LotSizeFilter LotSizeFilter `json:"lotSizeFilter"`
@ -108,18 +63,12 @@ type LotSizeFilter struct {
MinOrderQty string `json:"minOrderQty"` MinOrderQty string `json:"minOrderQty"`
QtyStep string `json:"qtyStep"` QtyStep string `json:"qtyStep"`
PostOnlyMaxOrderQty string `json:"postOnlyMaxOrderQty"` PostOnlyMaxOrderQty string `json:"postOnlyMaxOrderQty"`
BasePrecision string `json:"basePrecision"`
QuotePrecision string `json:"quotePrecision"`
MaxOrderAmt string `json:"maxOrderAmt"`
MinOrderAmt string `jsoN:"minOrderAmt"`
} }
// type OrderBookEntry struct { type OrderBookEntry struct {
// Price string `json:"0"` Price string `json:"0"`
// Size string `json:"1"` Size string `json:"1"`
// } }
type OrderBookEntry []string
type OrderBookInfo struct { type OrderBookInfo struct {
Symbol string `json:"s"` Symbol string `json:"s"`
@ -154,19 +103,11 @@ type TickerInfo struct {
Bid1Price string `json:"bid1Price"` Bid1Price string `json:"bid1Price"`
Ask1Price string `json:"ask1Price"` Ask1Price string `json:"ask1Price"`
Bid1Size string `json:"bid1Size"` Bid1Size string `json:"bid1Size"`
Ask1Iv string `json:"ask1Iv"`
Bid1Iv string `json:"bid1Iv"`
MarkIv string `json:"markIv"`
UnderlyingPrice string `json:"underlyingPrice"`
TotalVolume string `json:"totalVolume"`
TotalTurnover string `json:"totalTurnover"`
Change24h string `json:"change24h"`
UsdIndexPrice string `json:"usdIndexPrice"`
} }
type MarketTickers struct { type MarketTickers struct {
Category string `json:"category"` Category string `json:"category"`
List []*TickerInfo `json:"list"` List []TickerInfo `json:"list"`
} }
type FundingRateInfo struct { type FundingRateInfo struct {
@ -195,18 +136,6 @@ type PublicRecentTradeHistory struct {
List []TradeInfo `json:"list"` List []TradeInfo `json:"list"`
} }
type OpenInterestInfo struct {
Category string `json:"category"`
Symbol string `json:"symbol"`
List []OpenInterest `json:"list"`
NextPageCursor string `json:"nextPageCursor"`
}
type OpenInterest struct {
OpenInterest string `json:"openInterest"`
Timestamp string `json:"timeStamp"`
}
type VolatilityData struct { type VolatilityData struct {
Period int `json:"period"` Period int `json:"period"`
Value string `json:"value"` Value string `json:"value"`
@ -215,7 +144,7 @@ type VolatilityData struct {
type HistoricalVolatilityInfo struct { type HistoricalVolatilityInfo struct {
Category string `json:"category"` Category string `json:"category"`
List []VolatilityData `json:"result"` List []VolatilityData `json:"list"`
} }
type InsuranceData struct { type InsuranceData struct {
@ -233,8 +162,8 @@ type RiskLimitData struct {
Id int `json:"id"` Id int `json:"id"`
Symbol string `json:"symbol"` Symbol string `json:"symbol"`
RiskLimitValue string `json:"riskLimitValue"` RiskLimitValue string `json:"riskLimitValue"`
MaintenanceMargin string `json:"maintenanceMargin"` MaintenanceMargin float64 `json:"maintenanceMargin"`
InitialMargin string `json:"initialMargin"` InitialMargin float64 `json:"initialMargin"`
IsLowestRisk int `json:"isLowestRisk"` IsLowestRisk int `json:"isLowestRisk"`
MaxLeverage string `json:"maxLeverage"` MaxLeverage string `json:"maxLeverage"`
} }

View File

@ -2,6 +2,7 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"net/http" "net/http"
) )

View File

@ -2,9 +2,9 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
) )
type PositionClient struct { type PositionClient struct {

View File

@ -2,9 +2,9 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
) )
type PreUpgradeClient struct { type PreUpgradeClient struct {

View File

@ -1,6 +1,7 @@
package bybit_connector package bybit_connector
import ( import (
"encoding/json"
"fmt" "fmt"
"io" "io"
"log" "log"

View File

@ -2,9 +2,9 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
) )
type SpotLeverageClient struct { type SpotLeverageClient struct {

View File

@ -2,10 +2,10 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
) )
type SpotMarginClient struct { type SpotMarginClient struct {

View File

@ -2,10 +2,10 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"github.com/wuhewuhe/bybit.go.api/models"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
"gitea.computernetthings.ru/yash/bybit.go.api/models"
) )
type TradeClient struct { type TradeClient struct {

16
user.go
View File

@ -2,9 +2,9 @@ package bybit_connector
import ( import (
"context" "context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http" "net/http"
"gitea.computernetthings.ru/yash/bybit.go.api/handlers"
) )
type UserServiceClient struct { type UserServiceClient struct {
@ -193,7 +193,7 @@ func (s *UserServiceClient) GetSubUidList(ctx context.Context, opts ...RequestOp
return nil, err return nil, err
} }
r := &request{ r := &request{
method: http.MethodGet, method: http.MethodPost,
endpoint: "/v5/user/query-sub-members", endpoint: "/v5/user/query-sub-members",
secType: secTypeSigned, secType: secTypeSigned,
} }
@ -211,11 +211,15 @@ func (s *UserServiceClient) GetSubUidList(ctx context.Context, opts ...RequestOp
} }
func (s *UserServiceClient) GetAPIKeyInfo(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) { func (s *UserServiceClient) GetAPIKeyInfo(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{ r := &request{
method: http.MethodGet, method: http.MethodPost,
endpoint: "/v5/user/query-api", endpoint: "/v5/user/query-api",
secType: secTypeSigned, secType: secTypeSigned,
} }
r.setParams(s.params)
data, err := s.c.callAPI(ctx, r, opts...) data, err := s.c.callAPI(ctx, r, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -233,7 +237,7 @@ func (s *UserServiceClient) GetUidWalletType(ctx context.Context, opts ...Reques
return nil, err return nil, err
} }
r := &request{ r := &request{
method: http.MethodGet, method: http.MethodPost,
endpoint: "/v5/user/get-member-type", endpoint: "/v5/user/get-member-type",
secType: secTypeSigned, secType: secTypeSigned,
} }
@ -255,7 +259,7 @@ func (s *UserServiceClient) GetAffiliateUserInfo(ctx context.Context, opts ...Re
return nil, err return nil, err
} }
r := &request{ r := &request{
method: http.MethodGet, method: http.MethodPost,
endpoint: "/v5/user/aff-customer-info", endpoint: "/v5/user/aff-customer-info",
secType: secTypeSigned, secType: secTypeSigned,
} }