mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-17 07:26:48 +00:00
* few fixes and add ratelimiter * adds test * revert configtest.json changes * configtest updated * WIP: adds public endpoint support * WIP: adds public endpoint support * adds public endpoint support * WIP: adds auth. endpoint support * adds test for auth. endpoint * fixes * adds auth. endpoint support * WIP: ws support * WIP * WIP * WIP * WIP * WIP * WIP * WIP * Testing * Complete WS spot testing * adds support for ws events * minor change * WIP: adds REST support for CoinMarginedFutures * Fixes * WIP: adds REST support for CoinMarginedFutures * Fixes * improvement in SPOT REST * Typo fix * WIP: add REST support for CMF Account API * minor fixes * WIP: add support for CMF conditional orders and few minor fixes * complete support for CMF conditional orders * adds support for public CMF endpoint * adds support for CMF position API * Complete REST CMF support * WIP * Testing REST CMF support * Testing REST CMF support * Testing REST CMF support completed * WIP: add support for UMF * completed non-auth UMF * WIP: add support for REST Auth. UMF * WIP: add support for REST Auth. UMF and some improvements * WIP * WIP * WIP * completed REST UMF * renaming * adds REST support for futures * add testcases for UMF and some optimizations * add testcases for futures * Testing UMF, futures and its changes * Fixes * Fixes after testing * WIP * WIP * WIP * completed ws USDT futures support * WIP: ws support for futures * fixes in WS futures * fixes in WS support * roll back changes made for WS CMF, USDT and Futures * fixes * WIP * WIP * fixes * Steps for new PR * WIP * WIP * WIP * WIP * complete PR setup * fixes for successfully running tests * update in symbol for futures pair in test file * WIP * Fixes in test file and other minor fix * fix testdata/configtest.json * reset CONTRIBUTORS file * review changes * remove unwanted file * remove redundant code * improvisation * adds comment for exported functions * remove unwanted TODO and commented code * fix * improvisation * fix * defined errors * improvisation * improvisation * improvisation * updates test * adds comment for exported types * review changes * review changes * fix * fixes * Changes for making BYBIT compatible with existing code base * Test file changes * Changes for making BYBIT compatible with existing code base * Changes for making BYBIT compatible with existing code base * fix lint issues * fix * review changes * review changes * review changes * review changes * review changes * review changes * review changes * review changes * review changes * review changes * WIP * add test cases for new API's * minor improvements * add missing API and their tests * minor fixes * add bybitTime * add bybitTimeSec, bybitTimeMilliSec, bybitTimeNanoSec and necessary support * fix GetTradeHistory function * error handling * test fixes * add GetServerTime API * adds GetHistoricCandlesExtended and review changes * test fixes * minor fix * integrating CMF Bybit recent change log * minor fixes * adds extractCurrencyPair * minor fixes * minor fix * review changes * adds variable declaration of error * review commit * adds embeddable type in API response for all API and integrate it * fixes * adds authentication WS connection * review changes * review changes * compatible changes * adds asset to GetWithdrawalsHistory * adds asset_type in rpc.proto * adds asset argument in gctcli withdrawal request command * improve error handling in exchange API error * web socket fix * review changes * improvements * improvements * minor fix * review changes * fixing wrapper issues * fixes * fixes * review changes * add test cases * fix for GetActiveOrders * lint fixes * fixes in websocket * adds wrapper testcases * adds wrapper testcases * adds wrapper testcases * fixes * fix issue with GetHistoricCandlesExtended * fix merge issues * improving error reporting * adds wrapper testcases and a minor fix * gctrpc changes * adds test cases fixes in websocket * review changes for ws * review changes in WS * fix gctrpc * merge fixes * review changes * WIP * updates pair in configs * adds new asset USDCMarginedFutures * adds URL const for USDCMarginedFutures * adds API support * minor fixes * adds kline API * minor fix * adds API * adds API * adds API * WIP * WIP * WIP * adds support for USDC auth requests to SendAuthHTTPRequest * adds SendUSDCAuthHTTPRequest * run test and fix them * rollback support added for Auth. USDC request inside SendAuthHTTPRequest * adds API and test cases * adds API and test cases * adds APIs and test cases * adds APIs * adds rate limit for USDC * adds USDCMarginedFutures to wrapper * adds USDC testcases in wrapper and fix few issues * minor test fixes * minor test fixes * fix lint issues * WIP * Merge changes * minor fixes * remove "else" and optimize * review changes * review changes * review changes * fix lint issue * merge fix * fix test * fix templates and run them * changes after merge * review changes and improvements * code improvement * fixes with respect to changes in API response in documentation * fixed review change in test * adds check in CancelExistingOrder * update exchange template * review changes * adds GetDepositAddress API * WIP: adds GetOrderHistory * complete GetOrderHistory * fixes * adds test case * fixes and add WithdrawFund API * WIP * WIP * updating all SendAuthHTTPRequest call * adds WithdrawCryptocurrencyFunds * update test cases * fix lint issues * fixes after merge * adds GetAvailableTransferChains and few fixes * minor fix in GetDepositAddress * minor fix with WS ping/pong handling * add ping handler for WS Auth. * fix typo mistake * update doc
1115 lines
33 KiB
Go
1115 lines
33 KiB
Go
package bybit
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
"github.com/thrasher-corp/gocryptotrader/common/crypto"
|
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
|
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
|
|
)
|
|
|
|
const (
|
|
|
|
// public endpoint
|
|
usdcfuturesGetOrderbook = "/perpetual/usdc/openapi/public/v1/order-book"
|
|
usdcfuturesGetContracts = "/perpetual/usdc/openapi/public/v1/symbols"
|
|
usdcfuturesGetSymbols = "/perpetual/usdc/openapi/public/v1/tick"
|
|
usdcfuturesGetKlines = "/perpetual/usdc/openapi/public/v1/kline/list"
|
|
usdcfuturesGetMarkPriceKlines = "/perpetual/usdc/openapi/public/v1/mark-price-kline"
|
|
usdcfuturesGetIndexPriceKlines = "/perpetual/usdc/openapi/public/v1/index-price-kline"
|
|
usdcfuturesGetPremiumIndexKlines = "/perpetual/usdc/openapi/public/v1/premium-index-kline"
|
|
usdcfuturesGetOpenInterest = "/perpetual/usdc/openapi/public/v1/open-interest"
|
|
usdcfuturesGetLargeOrders = "/perpetual/usdc/openapi/public/v1/big-deal"
|
|
usdcfuturesGetAccountRatio = "/perpetual/usdc/openapi/public/v1/account-ratio"
|
|
usdcfuturesGetLatestTrades = "/option/usdc/openapi/public/v1/query-trade-latest"
|
|
usdcfuturesGetLastFundingRate = "/perpetual/usdc/openapi/public/v1/prev-funding-rate"
|
|
usdcfuturesGetRiskLimit = "/perpetual/usdc/openapi/public/v1/risk-limit/list"
|
|
|
|
// auth endpoint
|
|
usdcfuturesPlaceOrder = "/perpetual/usdc/openapi/private/v1/place-order"
|
|
usdcfuturesModifyOrder = "/perpetual/usdc/openapi/private/v1/replace-order"
|
|
usdcfuturesCancelOrder = "/perpetual/usdc/openapi/private/v1/cancel-order"
|
|
usdcfuturesCancelAllActiveOrder = "/perpetual/usdc/openapi/private/v1/cancel-all"
|
|
usdcfuturesGetActiveOrder = "/option/usdc/openapi/private/v1/query-active-orders"
|
|
usdcfuturesGetOrderHistory = "/option/usdc/openapi/private/v1/query-order-history"
|
|
usdcfuturesGetTradeHistory = "/option/usdc/openapi/private/v1/execution-list"
|
|
usdcfuturesGetTransactionLog = "/option/usdc/openapi/private/v1/query-transaction-log"
|
|
usdcfuturesGetWalletBalance = "/option/usdc/openapi/private/v1/query-wallet-balance"
|
|
usdcfuturesGetAssetInfo = "/option/usdc/openapi/private/v1/query-asset-info"
|
|
usdcfuturesGetMarginInfo = "/option/usdc/openapi/private/v1/query-margin-info"
|
|
usdcfuturesGetPosition = "/option/usdc/openapi/private/v1/query-position"
|
|
usdcfuturesSetLeverage = "/perpetual/usdc/openapi/private/v1/position/leverage/save"
|
|
usdcfuturesGetSettlementHistory = "/option/usdc/openapi/private/v1/session-settlement"
|
|
usdcfuturesSetRiskLimit = "/perpetual/usdc/openapi/private/v1/position/set-risk-limit"
|
|
usdcfuturesGetPredictedFundingRate = "/perpetual/usdc/openapi/private/v1/predicted-funding"
|
|
)
|
|
|
|
// GetUSDCFuturesOrderbook gets orderbook data for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCFuturesOrderbook(ctx context.Context, symbol currency.Pair) (*Orderbook, error) {
|
|
var resp Orderbook
|
|
data := struct {
|
|
Result []USDCOrderbookData `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
err = by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetOrderbook, params), usdcPublicRate, &data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for x := range data.Result {
|
|
switch data.Result[x].Side {
|
|
case sideBuy:
|
|
resp.Bids = append(resp.Bids, orderbook.Item{
|
|
Price: data.Result[x].Price,
|
|
Amount: data.Result[x].Size,
|
|
})
|
|
case sideSell:
|
|
resp.Asks = append(resp.Asks, orderbook.Item{
|
|
Price: data.Result[x].Price,
|
|
Amount: data.Result[x].Size,
|
|
})
|
|
default:
|
|
return nil, errInvalidSide
|
|
}
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
// GetUSDCContracts gets all contract information for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCContracts(ctx context.Context, symbol currency.Pair, direction string, limit int64) ([]USDCContract, error) {
|
|
resp := struct {
|
|
Data []USDCContract `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if !symbol.IsEmpty() {
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
}
|
|
|
|
if direction != "" {
|
|
params.Set("direction", direction)
|
|
}
|
|
if limit > 0 && limit <= 200 {
|
|
params.Set("limit", strconv.FormatInt(limit, 10))
|
|
}
|
|
|
|
return resp.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetContracts, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCSymbols gets all symbol information for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCSymbols(ctx context.Context, symbol currency.Pair) (USDCSymbol, error) {
|
|
resp := struct {
|
|
Data USDCSymbol `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return USDCSymbol{}, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
return resp.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetSymbols, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCKlines gets kline of symbol for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCKlines(ctx context.Context, symbol currency.Pair, period string, startTime time.Time, limit int64) ([]USDCKline, error) {
|
|
resp := struct {
|
|
Data []USDCKline `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return nil, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
if !common.StringDataCompare(validFuturesIntervals, period) {
|
|
return resp.Data, errInvalidPeriod
|
|
}
|
|
params.Set("period", period)
|
|
|
|
if startTime.IsZero() {
|
|
return nil, errInvalidStartTime
|
|
}
|
|
params.Set("startTime", strconv.FormatInt(startTime.Unix(), 10))
|
|
|
|
if limit > 0 && limit <= 200 {
|
|
params.Set("limit", strconv.FormatInt(limit, 10))
|
|
}
|
|
return resp.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetKlines, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCMarkPriceKlines gets mark price kline of symbol for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCMarkPriceKlines(ctx context.Context, symbol currency.Pair, period string, startTime time.Time, limit int64) ([]USDCKlineBase, error) {
|
|
resp := struct {
|
|
Data []USDCKlineBase `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return nil, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
if !common.StringDataCompare(validFuturesIntervals, period) {
|
|
return resp.Data, errInvalidPeriod
|
|
}
|
|
params.Set("period", period)
|
|
|
|
if startTime.IsZero() {
|
|
return nil, errInvalidStartTime
|
|
}
|
|
params.Set("startTime", strconv.FormatInt(startTime.Unix(), 10))
|
|
|
|
if limit > 0 && limit <= 200 {
|
|
params.Set("limit", strconv.FormatInt(limit, 10))
|
|
}
|
|
return resp.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetMarkPriceKlines, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCIndexPriceKlines gets index price kline of symbol for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCIndexPriceKlines(ctx context.Context, symbol currency.Pair, period string, startTime time.Time, limit int64) ([]USDCKlineBase, error) {
|
|
resp := struct {
|
|
Data []USDCKlineBase `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return nil, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
if !common.StringDataCompare(validFuturesIntervals, period) {
|
|
return resp.Data, errInvalidPeriod
|
|
}
|
|
params.Set("period", period)
|
|
|
|
if startTime.IsZero() {
|
|
return nil, errInvalidStartTime
|
|
}
|
|
params.Set("startTime", strconv.FormatInt(startTime.Unix(), 10))
|
|
|
|
if limit > 0 && limit <= 200 {
|
|
params.Set("limit", strconv.FormatInt(limit, 10))
|
|
}
|
|
return resp.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetIndexPriceKlines, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCPremiumIndexKlines gets premium index kline of symbol for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCPremiumIndexKlines(ctx context.Context, symbol currency.Pair, period string, startTime time.Time, limit int64) ([]USDCKlineBase, error) {
|
|
resp := struct {
|
|
Data []USDCKlineBase `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return nil, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
if !common.StringDataCompare(validFuturesIntervals, period) {
|
|
return resp.Data, errInvalidPeriod
|
|
}
|
|
params.Set("period", period)
|
|
|
|
if startTime.IsZero() {
|
|
return nil, errInvalidStartTime
|
|
}
|
|
params.Set("startTime", strconv.FormatInt(startTime.Unix(), 10))
|
|
|
|
if limit > 0 && limit <= 200 {
|
|
params.Set("limit", strconv.FormatInt(limit, 10))
|
|
}
|
|
return resp.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetPremiumIndexKlines, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCOpenInterest gets open interest of symbol for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCOpenInterest(ctx context.Context, symbol currency.Pair, period string, limit int64) ([]USDCOpenInterest, error) {
|
|
resp := struct {
|
|
Data []USDCOpenInterest `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return nil, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
if !common.StringDataCompare(validFuturesPeriods, period) {
|
|
return resp.Data, errInvalidPeriod
|
|
}
|
|
params.Set("period", period)
|
|
|
|
if limit > 0 && limit <= 200 {
|
|
params.Set("limit", strconv.FormatInt(limit, 10))
|
|
}
|
|
return resp.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetOpenInterest, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCLargeOrders gets large order of symbol for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCLargeOrders(ctx context.Context, symbol currency.Pair, limit int64) ([]USDCLargeOrder, error) {
|
|
resp := struct {
|
|
Data []USDCLargeOrder `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return nil, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
if limit > 0 && limit <= 100 {
|
|
params.Set("limit", strconv.FormatInt(limit, 10))
|
|
}
|
|
return resp.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetLargeOrders, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCAccountRatio gets account long short ratio of symbol for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCAccountRatio(ctx context.Context, symbol currency.Pair, period string, limit int64) ([]USDCAccountRatio, error) {
|
|
resp := struct {
|
|
Data []USDCAccountRatio `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return nil, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
if !common.StringDataCompare(validFuturesPeriods, period) {
|
|
return resp.Data, errInvalidPeriod
|
|
}
|
|
params.Set("period", period)
|
|
|
|
if limit > 0 && limit <= 500 {
|
|
params.Set("limit", strconv.FormatInt(limit, 10))
|
|
}
|
|
return resp.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetAccountRatio, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCLatestTrades gets latest 500 trades for USDCMarginedFutures.
|
|
func (by *Bybit) GetUSDCLatestTrades(ctx context.Context, symbol currency.Pair, category string, limit int64) ([]USDCTrade, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
ResultSize int64 `json:"resultTotalSize"`
|
|
Cursor string `json:"cursor"`
|
|
Data []USDCTrade `json:"dataList"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if category == "" {
|
|
return nil, errInvalidCategory
|
|
}
|
|
params.Set("category", category)
|
|
|
|
if !symbol.IsEmpty() {
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.Data, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
}
|
|
|
|
if limit > 0 && limit <= 500 {
|
|
params.Set("limit", strconv.FormatInt(limit, 10))
|
|
}
|
|
return resp.Result.Data, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetLatestTrades, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// PlaceUSDCOrder create new USDC derivatives order.
|
|
func (by *Bybit) PlaceUSDCOrder(ctx context.Context, symbol currency.Pair, orderType, orderFilter, side, timeInForce, orderLinkID string, orderPrice, orderQty, takeProfit, stopLoss, tptriggerby, slTriggerBy, triggerPrice, triggerBy float64, reduceOnly, closeOnTrigger, mmp bool) (USDCCreateOrderResp, error) {
|
|
resp := struct {
|
|
Result USDCCreateOrderResp `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if symbol.IsEmpty() {
|
|
return USDCCreateOrderResp{}, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
|
|
if orderType == "" {
|
|
return USDCCreateOrderResp{}, errInvalidOrderType
|
|
}
|
|
req["orderType"] = orderType
|
|
|
|
if orderFilter == "" {
|
|
return USDCCreateOrderResp{}, errInvalidOrderFilter
|
|
}
|
|
req["orderFilter"] = orderFilter
|
|
|
|
if side == "" {
|
|
return USDCCreateOrderResp{}, errInvalidSide
|
|
}
|
|
req["side"] = side
|
|
|
|
if orderQty == 0 {
|
|
return USDCCreateOrderResp{}, errInvalidQuantity
|
|
}
|
|
req["orderQty"] = strconv.FormatFloat(orderQty, 'f', -1, 64)
|
|
|
|
if orderPrice != 0 {
|
|
req["orderPrice"] = strconv.FormatFloat(orderPrice, 'f', -1, 64)
|
|
}
|
|
|
|
if timeInForce != "" {
|
|
req["timeInForce"] = timeInForce
|
|
}
|
|
|
|
if orderLinkID != "" {
|
|
req["orderLinkId"] = orderLinkID
|
|
}
|
|
|
|
if reduceOnly {
|
|
req["reduceOnly"] = true
|
|
} else {
|
|
req["reduceOnly"] = false
|
|
}
|
|
|
|
if closeOnTrigger {
|
|
req["closeOnTrigger"] = true
|
|
} else {
|
|
req["closeOnTrigger"] = false
|
|
}
|
|
|
|
if mmp {
|
|
req["mmp"] = true
|
|
} else {
|
|
req["mmp"] = false
|
|
}
|
|
|
|
if takeProfit != 0 {
|
|
req["takeProfit"] = strconv.FormatFloat(takeProfit, 'f', -1, 64)
|
|
}
|
|
|
|
if stopLoss != 0 {
|
|
req["stopLoss"] = strconv.FormatFloat(stopLoss, 'f', -1, 64)
|
|
}
|
|
|
|
if tptriggerby != 0 {
|
|
req["tptriggerby"] = tptriggerby
|
|
}
|
|
|
|
if slTriggerBy != 0 {
|
|
req["slTriggerBy"] = strconv.FormatFloat(slTriggerBy, 'f', -1, 64)
|
|
}
|
|
|
|
if triggerPrice != 0 {
|
|
req["triggerPrice"] = strconv.FormatFloat(triggerPrice, 'f', -1, 64)
|
|
}
|
|
|
|
if triggerBy != 0 {
|
|
req["triggerBy"] = triggerBy
|
|
}
|
|
return resp.Result, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesPlaceOrder, req, &resp, usdcPlaceOrderRate)
|
|
}
|
|
|
|
// ModifyUSDCOrder modifies USDC derivatives order.
|
|
func (by *Bybit) ModifyUSDCOrder(ctx context.Context, symbol currency.Pair, orderFilter, orderID, orderLinkID string, orderPrice, orderQty, takeProfit, stopLoss, tptriggerby, slTriggerBy, triggerPrice float64) (string, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
OrderID string `json:"orderId"`
|
|
OrderLinkedID string `json:"orderLinkId"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if symbol.IsEmpty() {
|
|
return resp.Result.OrderID, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.OrderID, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
|
|
if orderFilter == "" {
|
|
return resp.Result.OrderID, errInvalidOrderFilter
|
|
}
|
|
req["orderFilter"] = orderFilter
|
|
|
|
if orderID == "" && orderLinkID == "" {
|
|
return resp.Result.OrderID, errOrderOrOrderLinkIDMissing
|
|
}
|
|
|
|
if orderID != "" {
|
|
req["orderId"] = orderID
|
|
}
|
|
|
|
if orderLinkID != "" {
|
|
req["orderLinkId"] = orderLinkID
|
|
}
|
|
|
|
if orderPrice != 0 {
|
|
req["orderPrice"] = strconv.FormatFloat(orderPrice, 'f', -1, 64)
|
|
}
|
|
|
|
if orderQty != 0 {
|
|
req["orderQty"] = strconv.FormatFloat(orderQty, 'f', -1, 64)
|
|
}
|
|
|
|
if takeProfit != 0 {
|
|
req["takeProfit"] = strconv.FormatFloat(takeProfit, 'f', -1, 64)
|
|
}
|
|
|
|
if stopLoss != 0 {
|
|
req["stopLoss"] = strconv.FormatFloat(stopLoss, 'f', -1, 64)
|
|
}
|
|
|
|
if tptriggerby != 0 {
|
|
req["tptriggerby"] = strconv.FormatFloat(tptriggerby, 'f', -1, 64)
|
|
}
|
|
|
|
if slTriggerBy != 0 {
|
|
req["slTriggerBy"] = strconv.FormatFloat(slTriggerBy, 'f', -1, 64)
|
|
}
|
|
|
|
if triggerPrice != 0 {
|
|
req["triggerPrice"] = strconv.FormatFloat(triggerPrice, 'f', -1, 64)
|
|
}
|
|
return resp.Result.OrderID, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesModifyOrder, req, &resp, usdcModifyOrderRate)
|
|
}
|
|
|
|
// CancelUSDCOrder cancels USDC derivatives order.
|
|
func (by *Bybit) CancelUSDCOrder(ctx context.Context, symbol currency.Pair, orderFilter, orderID, orderLinkID string) (string, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
OrderID string `json:"orderId"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if symbol.IsEmpty() {
|
|
return resp.Result.OrderID, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.OrderID, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
|
|
if orderFilter == "" {
|
|
return resp.Result.OrderID, errInvalidOrderFilter
|
|
}
|
|
req["orderFilter"] = orderFilter
|
|
|
|
if orderID == "" && orderLinkID == "" {
|
|
return resp.Result.OrderID, errOrderOrOrderLinkIDMissing
|
|
}
|
|
|
|
if orderID != "" {
|
|
req["orderId"] = orderID
|
|
}
|
|
|
|
if orderLinkID != "" {
|
|
req["orderLinkId"] = orderLinkID
|
|
}
|
|
return resp.Result.OrderID, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesCancelOrder, req, &resp, usdcCancelOrderRate)
|
|
}
|
|
|
|
// CancelAllActiveUSDCOrder cancels all active USDC derivatives order.
|
|
func (by *Bybit) CancelAllActiveUSDCOrder(ctx context.Context, symbol currency.Pair, orderFilter string) error {
|
|
req := make(map[string]interface{})
|
|
if symbol.IsEmpty() {
|
|
return errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
|
|
if orderFilter == "" {
|
|
return errInvalidOrderFilter
|
|
}
|
|
req["orderFilter"] = orderFilter
|
|
return by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesCancelAllActiveOrder, req, nil, usdcCancelAllOrderRate)
|
|
}
|
|
|
|
// GetActiveUSDCOrder gets all active USDC derivatives order.
|
|
func (by *Bybit) GetActiveUSDCOrder(ctx context.Context, symbol currency.Pair, category, orderID, orderLinkID, orderFilter, direction, cursor string, limit int64) ([]USDCOrder, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
Cursor string `json:"cursor"`
|
|
ResultTotalSize int64 `json:"resultTotalSize"`
|
|
Data []USDCOrder `json:"dataList"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if !symbol.IsEmpty() {
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.Data, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
}
|
|
|
|
if category == "" {
|
|
return nil, errInvalidCategory
|
|
}
|
|
req["category"] = category
|
|
|
|
if orderID != "" {
|
|
req["orderId"] = orderID
|
|
}
|
|
|
|
if orderLinkID != "" {
|
|
req["orderLinkId"] = orderLinkID
|
|
}
|
|
|
|
if orderFilter != "" {
|
|
req["orderFilter"] = orderFilter
|
|
}
|
|
|
|
if direction != "" {
|
|
req["direction"] = direction
|
|
}
|
|
|
|
if limit != 0 {
|
|
req["limit"] = strconv.FormatInt(limit, 10)
|
|
}
|
|
|
|
if cursor != "" {
|
|
req["cursor"] = cursor
|
|
}
|
|
return resp.Result.Data, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetActiveOrder, req, &resp, usdcGetOrderRate)
|
|
}
|
|
|
|
// GetUSDCOrderHistory gets order history with support of last 30 days of USDC derivatives order.
|
|
func (by *Bybit) GetUSDCOrderHistory(ctx context.Context, symbol currency.Pair, category, orderID, orderLinkID, orderStatus, direction, cursor string, limit int64) ([]USDCOrderHistory, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
Cursor string `json:"cursor"`
|
|
ResultTotalSize int64 `json:"resultTotalSize"`
|
|
Data []USDCOrderHistory `json:"dataList"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if !symbol.IsEmpty() {
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.Data, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
}
|
|
|
|
if category == "" {
|
|
return nil, errInvalidCategory
|
|
}
|
|
req["category"] = category
|
|
|
|
if orderID != "" {
|
|
req["orderId"] = orderID
|
|
}
|
|
|
|
if orderLinkID != "" {
|
|
req["orderLinkId"] = orderLinkID
|
|
}
|
|
|
|
if orderStatus != "" {
|
|
req["orderStatus"] = orderStatus
|
|
}
|
|
|
|
if direction != "" {
|
|
req["direction"] = direction
|
|
}
|
|
|
|
if limit != 0 {
|
|
req["limit"] = strconv.FormatInt(limit, 10)
|
|
}
|
|
|
|
if cursor != "" {
|
|
req["cursor"] = cursor
|
|
}
|
|
return resp.Result.Data, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetOrderHistory, req, &resp, usdcGetOrderHistoryRate)
|
|
}
|
|
|
|
// GetUSDCTradeHistory gets trade history with support of last 30 days of USDC derivatives trades.
|
|
func (by *Bybit) GetUSDCTradeHistory(ctx context.Context, symbol currency.Pair, category, orderID, orderLinkID, direction, cursor string, limit int64, startTime time.Time) ([]USDCTradeHistory, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
Cursor string `json:"cursor"`
|
|
ResultTotalSize int64 `json:"resultTotalSize"`
|
|
Data []USDCTradeHistory `json:"dataList"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if !symbol.IsEmpty() {
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.Data, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
}
|
|
|
|
if category == "" {
|
|
return nil, errInvalidCategory
|
|
}
|
|
req["category"] = category
|
|
|
|
if orderID == "" && orderLinkID == "" {
|
|
return nil, errOrderOrOrderLinkIDMissing
|
|
}
|
|
|
|
if orderID != "" {
|
|
req["orderId"] = orderID
|
|
}
|
|
|
|
if orderLinkID != "" {
|
|
req["orderLinkId"] = orderLinkID
|
|
}
|
|
|
|
if startTime.IsZero() {
|
|
return nil, errInvalidStartTime
|
|
}
|
|
req["startTime"] = strconv.FormatInt(startTime.Unix(), 10)
|
|
|
|
if direction != "" {
|
|
req["direction"] = direction
|
|
}
|
|
|
|
if limit > 0 && limit <= 50 {
|
|
req["limit"] = strconv.FormatInt(limit, 10)
|
|
}
|
|
|
|
if cursor != "" {
|
|
req["cursor"] = cursor
|
|
}
|
|
return resp.Result.Data, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetTradeHistory, req, &resp, usdcGetTradeHistoryRate)
|
|
}
|
|
|
|
// GetUSDCTransactionLog gets transaction logs with support of last 30 days of USDC derivatives trades.
|
|
func (by *Bybit) GetUSDCTransactionLog(ctx context.Context, startTime, endTime time.Time, txType, category, direction, cursor string, limit int64) ([]USDCTxLog, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
Cursor string `json:"cursor"`
|
|
ResultTotalSize int64 `json:"resultTotalSize"`
|
|
Data []USDCTxLog `json:"dataList"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if !startTime.IsZero() {
|
|
req["startTime"] = strconv.FormatInt(startTime.Unix(), 10)
|
|
}
|
|
|
|
if !endTime.IsZero() {
|
|
req["endTime"] = strconv.FormatInt(endTime.Unix(), 10)
|
|
}
|
|
|
|
if txType == "" {
|
|
return nil, errors.New("type missing")
|
|
}
|
|
req["type"] = txType
|
|
|
|
if category != "" {
|
|
req["category"] = category
|
|
}
|
|
|
|
if direction != "" {
|
|
req["direction"] = direction
|
|
}
|
|
|
|
if limit > 0 && limit <= 50 {
|
|
req["limit"] = strconv.FormatInt(limit, 10)
|
|
}
|
|
|
|
if cursor != "" {
|
|
req["cursor"] = cursor
|
|
}
|
|
return resp.Result.Data, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetTransactionLog, req, &resp, usdcGetTransactionRate)
|
|
}
|
|
|
|
// GetUSDCWalletBalance gets USDC wallet balance.
|
|
func (by *Bybit) GetUSDCWalletBalance(ctx context.Context) (USDCWalletBalance, error) {
|
|
resp := struct {
|
|
Result USDCWalletBalance `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
return resp.Result, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetWalletBalance, nil, &resp, usdcGetWalletRate)
|
|
}
|
|
|
|
// GetUSDCAssetInfo gets USDC asset information.
|
|
func (by *Bybit) GetUSDCAssetInfo(ctx context.Context, baseCoin string) ([]USDCAssetInfo, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
ResultTotalSize int64 `json:"resultTotalSize"`
|
|
Data []USDCAssetInfo `json:"dataList"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if baseCoin != "" {
|
|
req["baseCoin"] = baseCoin
|
|
}
|
|
|
|
return resp.Result.Data, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetAssetInfo, req, &resp, usdcGetAssetRate)
|
|
}
|
|
|
|
// GetUSDCMarginInfo gets USDC account margin information.
|
|
func (by *Bybit) GetUSDCMarginInfo(ctx context.Context) (string, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
MarginMode string `json:"marginMode"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
return resp.Result.MarginMode, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetMarginInfo, nil, &resp, usdcGetMarginRate)
|
|
}
|
|
|
|
// GetUSDCPosition gets USDC position information.
|
|
func (by *Bybit) GetUSDCPosition(ctx context.Context, symbol currency.Pair, category, direction, cursor string, limit int64) ([]USDCPosition, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
Cursor string `json:"cursor"`
|
|
ResultTotalSize int64 `json:"resultTotalSize"`
|
|
Data []USDCPosition `json:"dataList"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if !symbol.IsEmpty() {
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.Data, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
}
|
|
|
|
if category == "" {
|
|
return nil, errInvalidCategory
|
|
}
|
|
req["category"] = category
|
|
|
|
if cursor != "" {
|
|
req["cursor"] = cursor
|
|
}
|
|
|
|
if direction != "" {
|
|
req["direction"] = direction
|
|
}
|
|
|
|
if limit > 0 && limit <= 50 {
|
|
req["limit"] = strconv.FormatInt(limit, 10)
|
|
}
|
|
|
|
return resp.Result.Data, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetPosition, req, &resp, usdcGetPositionRate)
|
|
}
|
|
|
|
// SetUSDCLeverage sets USDC leverage.
|
|
func (by *Bybit) SetUSDCLeverage(ctx context.Context, symbol currency.Pair, leverage float64) (float64, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
Leverage float64 `json:"leverage,string"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if symbol.IsEmpty() {
|
|
return 0, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.Leverage, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
|
|
if leverage <= 0 {
|
|
return 0, errInvalidLeverage
|
|
}
|
|
req["leverage"] = strconv.FormatFloat(leverage, 'f', -1, 64)
|
|
|
|
return resp.Result.Leverage, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesSetLeverage, req, &resp, usdcSetLeverageRate)
|
|
}
|
|
|
|
// GetUSDCSettlementHistory gets USDC settlement history with support of last 30 days.
|
|
func (by *Bybit) GetUSDCSettlementHistory(ctx context.Context, symbol currency.Pair, direction, cursor string, limit int64) ([]USDCSettlementHistory, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
Cursor string `json:"cursor"`
|
|
ResultTotalSize int64 `json:"resultTotalSize"`
|
|
Data []USDCSettlementHistory `json:"dataList"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if symbol.IsEmpty() {
|
|
return resp.Result.Data, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.Data, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
|
|
if cursor != "" {
|
|
req["cursor"] = cursor
|
|
}
|
|
|
|
if direction != "" {
|
|
req["direction"] = direction
|
|
}
|
|
|
|
if limit > 0 && limit <= 50 {
|
|
req["limit"] = strconv.FormatInt(limit, 10)
|
|
}
|
|
|
|
return resp.Result.Data, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetSettlementHistory, req, &resp, usdcGetSettlementRate)
|
|
}
|
|
|
|
// GetUSDCRiskLimit gets USDC risk limits data.
|
|
func (by *Bybit) GetUSDCRiskLimit(ctx context.Context, symbol currency.Pair) ([]USDCRiskLimit, error) {
|
|
resp := struct {
|
|
Result []USDCRiskLimit `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return nil, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
return resp.Result, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetRiskLimit, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// SetUSDCRiskLimit sets USDC risk limit.
|
|
func (by *Bybit) SetUSDCRiskLimit(ctx context.Context, symbol currency.Pair, riskID int64) (string, error) {
|
|
resp := struct {
|
|
Result struct {
|
|
RiskID string `json:"riskId"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
if symbol.IsEmpty() {
|
|
return resp.Result.RiskID, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.RiskID, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
|
|
if riskID <= 0 {
|
|
return resp.Result.RiskID, errInvalidRiskID
|
|
}
|
|
req["riskId"] = riskID
|
|
|
|
return resp.Result.RiskID, by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesSetRiskLimit, req, &resp, usdcSetRiskRate)
|
|
}
|
|
|
|
// GetUSDCLastFundingRate gets USDC last funding rates.
|
|
func (by *Bybit) GetUSDCLastFundingRate(ctx context.Context, symbol currency.Pair) (USDCFundingInfo, error) {
|
|
resp := struct {
|
|
Result USDCFundingInfo `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
params := url.Values{}
|
|
if symbol.IsEmpty() {
|
|
return resp.Result, errSymbolMissing
|
|
}
|
|
symbolValue, err := by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result, err
|
|
}
|
|
params.Set("symbol", symbolValue)
|
|
|
|
return resp.Result, by.SendHTTPRequest(ctx, exchange.RestUSDCMargined, common.EncodeURLValues(usdcfuturesGetLastFundingRate, params), usdcPublicRate, &resp)
|
|
}
|
|
|
|
// GetUSDCPredictedFundingRate gets predicted funding rates and my predicted funding fee.
|
|
func (by *Bybit) GetUSDCPredictedFundingRate(ctx context.Context, symbol currency.Pair) (predictedFundingRate, predictedFundingFee float64, err error) {
|
|
resp := struct {
|
|
Result struct {
|
|
PredictedFundingRate float64 `json:"predictedFundingRate,string"`
|
|
PredictedFundingFee float64 `json:"predictedFundingFee,string"`
|
|
} `json:"result"`
|
|
USDCError
|
|
}{}
|
|
|
|
req := make(map[string]interface{})
|
|
var symbolValue string
|
|
if symbol.IsEmpty() {
|
|
return resp.Result.PredictedFundingRate, resp.Result.PredictedFundingFee, errSymbolMissing
|
|
}
|
|
symbolValue, err = by.FormatSymbol(symbol, asset.USDCMarginedFutures)
|
|
if err != nil {
|
|
return resp.Result.PredictedFundingRate, resp.Result.PredictedFundingFee, err
|
|
}
|
|
req["symbol"] = symbolValue
|
|
|
|
err = by.SendUSDCAuthHTTPRequest(ctx, exchange.RestUSDCMargined, http.MethodPost, usdcfuturesGetPredictedFundingRate, req, &resp, usdcGetPredictedFundingRate)
|
|
predictedFundingRate = resp.Result.PredictedFundingRate
|
|
predictedFundingFee = resp.Result.PredictedFundingFee
|
|
return
|
|
}
|
|
|
|
// SendUSDCAuthHTTPRequest sends an authenticated HTTP request
|
|
func (by *Bybit) SendUSDCAuthHTTPRequest(ctx context.Context, ePath exchange.URL, method, path string, data interface{}, result UnmarshalTo, f request.EndpointLimit) error {
|
|
creds, err := by.GetCredentials(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if result == nil {
|
|
result = &USDCError{}
|
|
}
|
|
|
|
endpointPath, err := by.API.Endpoints.GetURL(ePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = by.SendPayload(ctx, f, func() (*request.Item, error) {
|
|
nowTimeInMilli := strconv.FormatInt(time.Now().UnixMilli(), 10)
|
|
headers := make(map[string]string)
|
|
var payload, hmacSigned []byte
|
|
|
|
if data != nil {
|
|
d, ok := data.(map[string]interface{})
|
|
if !ok {
|
|
return nil, common.GetAssertError("map[string]interface{}", data)
|
|
}
|
|
payload, err = json.Marshal(d)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
signInput := nowTimeInMilli + creds.Key + defaultRecvWindow + string(payload)
|
|
hmacSigned, err = crypto.GetHMAC(crypto.HashSHA256, []byte(signInput), []byte(creds.Secret))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
headers["Content-Type"] = "application/json"
|
|
headers["X-BAPI-API-KEY"] = creds.Key
|
|
headers["X-BAPI-SIGN"] = crypto.HexEncodeToString(hmacSigned)
|
|
headers["X-BAPI-SIGN-TYPE"] = "2"
|
|
headers["X-BAPI-TIMESTAMP"] = nowTimeInMilli
|
|
headers["X-BAPI-RECV-WINDOW"] = defaultRecvWindow
|
|
|
|
return &request.Item{
|
|
Method: method,
|
|
Path: endpointPath + path,
|
|
Headers: headers,
|
|
Body: bytes.NewBuffer(payload),
|
|
Result: &result,
|
|
AuthRequest: true,
|
|
Verbose: by.Verbose,
|
|
HTTPDebugging: by.HTTPDebugging,
|
|
HTTPRecording: by.HTTPRecording}, nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return result.GetError()
|
|
}
|
|
|
|
// USDCError defines all error information for each USDC request
|
|
type USDCError struct {
|
|
ReturnCode int64 `json:"retCode"`
|
|
ReturnMsg string `json:"retMsg"`
|
|
}
|
|
|
|
// GetError checks and returns an error if it is supplied.
|
|
func (e USDCError) GetError() error {
|
|
if e.ReturnCode != 0 && e.ReturnMsg != "" {
|
|
return errors.New(e.ReturnMsg)
|
|
}
|
|
return nil
|
|
}
|