Merge pull request #12 from wuhewuhe/master

spot leverage to do spot margin
This commit is contained in:
CommaHunger 2023-11-06 12:40:28 +01:00 committed by GitHub
commit 9bc3022d2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 464 additions and 0 deletions

View File

@ -302,3 +302,18 @@ func (c *Client) NewLendingServiceNoParams() *LendingServiceClient {
c: c,
}
}
func (c *Client) NewSpotLeverageService(params map[string]interface{}) *SpotLeverageClient {
return &SpotLeverageClient{
c: c,
params: params,
}
}
func (c *Client) NewSpotMarginDataService(params map[string]interface{}, isUta bool) *SpotMarginClient {
return &SpotMarginClient{
c: c,
isUta: isUta,
params: params,
}
}

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("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", 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("8wYkmpLsMg10eNQyPm", "Ouxc34myDnXvei54XsBZgoQzfGxO4bkr2Zsj", 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,78 @@
package models
import "time"
// SpotLeverageTokenInfo holds the information for leveraged tokens.
type SpotLeverageTokenInfo struct {
List []struct {
LtCoin string `json:"ltCoin"`
LtName string `json:"ltName"`
MaxPurchase string `json:"maxPurchase"`
MinPurchase string `json:"minPurchase"`
MaxPurchaseDaily string `json:"maxPurchaseDaily"`
MaxRedeem string `json:"maxRedeem"`
MinRedeem string `json:"minRedeem"`
MaxRedeemDaily string `json:"maxRedeemDaily"`
PurchaseFeeRate string `json:"purchaseFeeRate"`
RedeemFeeRate string `json:"redeemFeeRate"`
LtStatus string `json:"ltStatus"`
FundFee string `json:"fundFee"`
FundFeeTime string `json:"fundFeeTime"` // Should parse to time.Time if needed
ManageFeeRate string `json:"manageFeeRate"`
ManageFeeTime string `json:"manageFeeTime"` // Should parse to time.Time if needed
Value string `json:"value"`
NetValue string `json:"netValue"`
Total string `json:"total"`
}
}
// SpotLeverageTokenMarket holds the market information for a leveraged token.
type SpotLeverageTokenMarket struct {
LtCoin string `json:"ltCoin"`
Nav string `json:"nav"`
NavTime time.Time `json:"navTime"` // Assuming time is in milliseconds, need to convert
Circulation string `json:"circulation"`
Basket string `json:"basket"`
Leverage string `json:"leverage"`
}
// SpotLeverageOrdersRecords holds the orders records for leveraged tokens.
type SpotLeverageOrdersRecords struct {
List []struct {
LtCoin string `json:"ltCoin"`
OrderId string `json:"orderId"`
LtOrderType int `json:"ltOrderType"` // Use int for integer type
OrderTime int64 `json:"orderTime"` // Assuming this is a timestamp, int64 is used
UpdateTime int64 `json:"updateTime"` // Assuming this is a timestamp, int64 is used
LtOrderStatus string `json:"ltOrderStatus"`
Fee string `json:"fee"`
Amount string `json:"amount"`
Value string `json:"value"`
ValueCoin string `json:"valueCoin"`
SerialNo string `json:"serialNo"`
}
}
// LeverageTokenPurchaseResult represents the result of a leverage token purchase.
type LeverageTokenPurchaseResult struct {
LtCoin string `json:"ltCoin"`
LtOrderStatus string `json:"ltOrderStatus"`
ExecQty string `json:"execQty"`
ExecAmt string `json:"execAmt"`
Amount string `json:"amount"`
PurchaseId string `json:"purchaseId"`
SerialNo string `json:"serialNo"`
ValueCoin string `json:"valueCoin"`
}
// LeverageTokenRedeem represents the redeem information for a leveraged token.
type LeverageTokenRedeem struct {
LtCoin string `json:"ltCoin"`
LtOrderStatus string `json:"ltOrderStatus"`
Quantity string `json:"quantity"`
ExecQty string `json:"execQty"`
ExecAmt string `json:"execAmt"`
RedeemId string `json:"redeemId"`
SerialNo string `json:"serialNo"`
ValueCoin string `json:"valueCoin"`
}

View File

@ -0,0 +1,61 @@
package models
// SpotMarginDataResult holds data for spot margin including VIP level specific coin list.
type SpotMarginDataResult struct {
VipCoinList []struct {
List []struct {
Borrowable bool `json:"borrowable"`
CollateralRatio string `json:"collateralRatio"`
Currency string `json:"currency"`
HourlyBorrowRate string `json:"hourlyBorrowRate"`
LiquidationOrder string `json:"liquidationOrder"`
MarginCollateral bool `json:"marginCollateral"`
MaxBorrowingAmount string `json:"maxBorrowingAmount"`
} `json:"list"`
VipLevel string `json:"vipLevel"`
} `json:"vipCoinList"`
}
// ClassicalSpotMarginCoinResult holds information about coins in classical spot margin.
type ClassicalSpotMarginCoinResult struct {
List []struct {
Coin string `json:"coin"`
ConversionRate string `json:"conversionRate"`
LiquidationOrder int `json:"liquidationOrder"`
} `json:"list"`
}
// ClassicalSpotMarginBorrowCoinResult holds the borrowing precision information for coins in classical spot margin.
type ClassicalSpotMarginBorrowCoinResult struct {
List []struct {
Coin string `json:"coin"`
BorrowingPrecision int `json:"borrowingPrecision"`
RepaymentPrecision int `json:"repaymentPrecision"`
} `json:"list"`
}
// ClassicalSpotMarginInterestResult contains information about the interest rate on spot margin.
type ClassicalSpotMarginInterestResult struct {
Coin string `json:"coin"`
InterestRate string `json:"interestRate"`
LoanAbleAmount string `json:"loanAbleAmount"`
MaxLoanAmount string `json:"maxLoanAmount"`
}
// ClassicalSpotMarginLoanResult holds the loan account information in the classical spot margin.
type ClassicalSpotMarginLoanResult struct {
AcctBalanceSum string `json:"acctBalanceSum"`
DebtBalanceSum string `json:"debtBalanceSum"`
LoanAccountList []struct {
Free string `json:"free"`
Interest string `json:"interest"`
Loan string `json:"loan"`
RemainAmount string `json:"remainAmount"`
Locked string `json:"locked"`
TokenId string `json:"tokenId"`
Total string `json:"total"`
} `json:"loanAccountList"`
RiskRate string `json:"riskRate"`
Status int `json:"status"` // Use int for integer type
SwitchStatus int `json:"switchStatus"` // Use int for integer type
}

123
spot_leverage.go Normal file
View File

@ -0,0 +1,123 @@
package bybit_connector
import (
"context"
"encoding/json"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http"
)
type SpotLeverageClient struct {
c *Client
params map[string]interface{}
}
func (s *SpotLeverageClient) GetLeverageTokenInfo(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/spot-lever-token/info",
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 *SpotLeverageClient) GetLeverageTokenOrders(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/spot-lever-token/order-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 *SpotLeverageClient) GetLeverageTokenMarket(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/spot-lever-token/reference",
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 *SpotLeverageClient) PurchaseLeverageToken(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodPost,
endpoint: "/v5/spot-lever-token/purchase",
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 *SpotLeverageClient) RedeemLeverageToken(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodPost,
endpoint: "/v5/spot-lever-token/redeem",
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
}

143
spot_margin.go Normal file
View File

@ -0,0 +1,143 @@
package bybit_connector
import (
"context"
"encoding/json"
"errors"
"github.com/wuhewuhe/bybit.go.api/handlers"
"net/http"
)
type SpotMarginClient struct {
c *Client
isUta bool
params map[string]interface{}
}
func (s *SpotMarginClient) GetSpotMarginData(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
var endpoint string
if !s.isUta {
endpoint = "/v5/spot-margin-trade/data"
} else {
endpoint = "/v5/spot-cross-margin-trade/data"
}
r := &request{
method: http.MethodGet,
endpoint: endpoint,
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 *SpotMarginClient) GetSpotMarginCoin(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if s.isUta {
return nil, errors.New("this function only works for classical accounts")
}
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/spot-cross-margin-trade/pledge-token",
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 *SpotMarginClient) GetSpotMarginBorrowCoin(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if s.isUta {
return nil, errors.New("this function only works for classical accounts")
}
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/spot-cross-margin-trade/borrow-token",
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 *SpotMarginClient) GetSpotMarginInterests(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if s.isUta {
return nil, errors.New("this function only works for classical accounts")
}
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/spot-cross-margin-trade/loan-info",
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 *SpotMarginClient) GetSpotMarginLoanAccountInfo(ctx context.Context, opts ...RequestOption) (res *ServerResponse, err error) {
if s.isUta {
return nil, errors.New("this function only works for classical accounts")
}
if err = handlers.ValidateParams(s.params); err != nil {
return nil, err
}
r := &request{
method: http.MethodGet,
endpoint: "/v5/spot-cross-margin-trade/account",
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
}