Skip to content

Commit

Permalink
Bitget progress
Browse files Browse the repository at this point in the history
  • Loading branch information
cranktakular committed Jun 11, 2024
1 parent c44723a commit 7904cde
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 23 deletions.
90 changes: 87 additions & 3 deletions exchanges/bitget/bitget.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ const (
bitgetSharkFin = "sharkfin"
bitgetOngoingOrders = "/ongoing-orders"
bitgetRevisePledge = "/revise-pledge"
bitgetReviseHistory = "/revise-history"
bitgetDebts = "/debts"
bitgetReduces = "/reduces"

// Errors
errUnknownEndpointLimit = "unknown endpoint limit %v"
Expand Down Expand Up @@ -590,6 +593,8 @@ func (bi *Bitget) GetAPIKeys(ctx context.Context, subaccountID string) (*GetAPIK
nil, &resp)
}

// GetFundingAssets returns the user's assets

// GetConvertCoins returns a list of supported currencies, your balance in those currencies, and the maximum and
// minimum tradable amounts of those currencies
func (bi *Bitget) GetConvertCoins(ctx context.Context) (*ConvertCoinsResp, error) {
Expand Down Expand Up @@ -4143,11 +4148,11 @@ func (bi *Bitget) GetLoanRepayHistory(ctx context.Context, orderID, pagination,
}

// ModifyPledgeRate modifies the amount of collateral pledged for a loan
func (bi *Bitget) ModifyPledgeRate(ctx context.Context, orderID int64, amoutn float64, pledgeCoin, reviseType string) (*ModPledgeResp, error) {
func (bi *Bitget) ModifyPledgeRate(ctx context.Context, orderID int64, amount float64, pledgeCoin, reviseType string) (*ModPledgeResp, error) {
if orderID == 0 {
return nil, errOrderIDEmpty
}
if amoutn == 0 {
if amount == 0 {
return nil, errAmountEmpty
}
if pledgeCoin == "" {
Expand All @@ -4158,7 +4163,7 @@ func (bi *Bitget) ModifyPledgeRate(ctx context.Context, orderID int64, amoutn fl
}
req := map[string]interface{}{
"orderId": orderID,
"amount": strconv.FormatFloat(amoutn, 'f', -1, 64),
"amount": strconv.FormatFloat(amount, 'f', -1, 64),
"pledgeCoin": pledgeCoin,
"reviseType": reviseType,
}
Expand All @@ -4168,6 +4173,85 @@ func (bi *Bitget) ModifyPledgeRate(ctx context.Context, orderID int64, amoutn fl
&resp)
}

// GetPledgeRateHistory returns the history of pledged rates for loans
func (bi *Bitget) GetPledgeRateHistory(ctx context.Context, orderID, pagination, limit int64, reviseSide, pledgeCoin string, startTime, endTime time.Time) (*PledgeRateHist, error) {
var params Params
params.Values = make(url.Values)
err := params.prepareDateString(startTime, endTime, false, false)
if err != nil {
return nil, err
}
params.Values.Set("orderId", strconv.FormatInt(orderID, 10))
params.Values.Set("reviseSide", reviseSide)
params.Values.Set("pledgeCoin", pledgeCoin)
if pagination != 0 {
params.Values.Set("idLessThan", strconv.FormatInt(pagination, 10))
}
if limit != 0 {
params.Values.Set("limit", strconv.FormatInt(limit, 10))
}
path := bitgetEarn + bitgetLoan + bitgetReviseHistory
var resp *PledgeRateHist
return resp, bi.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, Rate10, http.MethodGet, path, params.Values,
nil, &resp)
}

// GetLoanHistory returns the loan history
func (bi *Bitget) GetLoanHistory(ctx context.Context, orderID, pagination, limit int64, loanCoin, pledgeCoin, status string, startTime, endTime time.Time) (*LoanHistory, error) {
var params Params
params.Values = make(url.Values)
err := params.prepareDateString(startTime, endTime, false, false)
if err != nil {
return nil, err
}
params.Values.Set("orderId", strconv.FormatInt(orderID, 10))
params.Values.Set("loanCoin", loanCoin)
params.Values.Set("pledgeCoin", pledgeCoin)
params.Values.Set("status", status)
if pagination != 0 {
params.Values.Set("idLessThan", strconv.FormatInt(pagination, 10))
}
if limit != 0 {
params.Values.Set("limit", strconv.FormatInt(limit, 10))
}
path := bitgetEarn + bitgetLoan + bitgetBorrowHistory
var resp *LoanHistory
return resp, bi.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, Rate10, http.MethodGet, path, params.Values,
nil, &resp)
}

// GetDebts returns information on current outstanding pledges and loans
func (bi *Bitget) GetDebts(ctx context.Context) (*DebtsResp, error) {
path := bitgetEarn + bitgetLoan + bitgetDebts
var resp *DebtsResp
return resp, bi.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, Rate10, http.MethodGet, path, nil, nil,
&resp)
}

// GetLiquidationRecords returns the liquidation records
func (bi *Bitget) GetLiquidationRecords(ctx context.Context, orderID, pagination, limit int64, loanCoin, pledgeCoin, status string, startTime, endTime time.Time) (*LiquidRecs, error) {
var params Params
params.Values = make(url.Values)
err := params.prepareDateString(startTime, endTime, false, false)
if err != nil {
return nil, err
}
params.Values.Set("orderId", strconv.FormatInt(orderID, 10))
params.Values.Set("loanCoin", loanCoin)
params.Values.Set("pledgeCoin", pledgeCoin)
params.Values.Set("status", status)
if pagination != 0 {
params.Values.Set("idLessThan", strconv.FormatInt(pagination, 10))
}
if limit != 0 {
params.Values.Set("limit", strconv.FormatInt(limit, 10))
}
path := bitgetEarn + bitgetLoan + bitgetReduces
var resp *LiquidRecs
return resp, bi.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, Rate10, http.MethodGet, path, params.Values,
nil, &resp)
}

// SendAuthenticatedHTTPRequest sends an authenticated HTTP request
func (bi *Bitget) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, rateLim request.EndpointLimit, method, path string, queryParams url.Values, bodyParams map[string]interface{}, result interface{}) error {
creds, err := bi.GetCredentials(ctx)
Expand Down
84 changes: 75 additions & 9 deletions exchanges/bitget/bitget_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/config"
"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/sharedtestvalues"
)

Expand Down Expand Up @@ -2298,30 +2299,77 @@ func TestGetOngoingLoans(t *testing.T) {
assert.NoError(t, err)
}

func TestRepayLoan(t *testing.T) {
func TestGetLoanRepayHistory(t *testing.T) {
t.Parallel()
_, err := bi.RepayLoan(context.Background(), 0, 0, false, false)
_, err := bi.GetLoanRepayHistory(context.Background(), 0, 0, 0, "", "", time.Time{}, time.Time{})
assert.ErrorIs(t, err, common.ErrDateUnset)
sharedtestvalues.SkipTestIfCredentialsUnset(t, bi)
_, err = bi.GetLoanRepayHistory(context.Background(), 0, 1, 5, "", "", time.Now().Add(-time.Hour*24*85), time.Now())
assert.NoError(t, err)
}

func TestModifyPledgeRate(t *testing.T) {
t.Parallel()
_, err := bi.ModifyPledgeRate(context.Background(), 0, 0, "", "")
assert.ErrorIs(t, err, errOrderIDEmpty)
_, err = bi.RepayLoan(context.Background(), 1, 0, false, false)
_, err = bi.ModifyPledgeRate(context.Background(), 1, 0, "", "")
assert.ErrorIs(t, err, errAmountEmpty)
_, err = bi.ModifyPledgeRate(context.Background(), 1, 1, "", "")
assert.ErrorIs(t, err, errCollateralCoinEmpty)
_, err = bi.ModifyPledgeRate(context.Background(), 1, 1, "meow", "")
assert.ErrorIs(t, err, errReviseTypeEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders)
resp, err := bi.GetOngoingLoans(context.Background(), 0, "", "")
require.NoError(t, err)
if len(resp.Data) == 0 {
t.Skip(skipInsufficientOrders)
}
_, err = bi.RepayLoan(context.Background(), resp.Data[0].OrderID, testAmount, false, false)
_, err = bi.ModifyPledgeRate(context.Background(), resp.Data[0].OrderID, testAmount, testFiat.String(), "IN")
assert.NoError(t, err)
_, err = bi.RepayLoan(context.Background(), resp.Data[0].OrderID, 0, true, true)
}

func TestGetPledgeRateHistory(t *testing.T) {
t.Parallel()
_, err := bi.GetPledgeRateHistory(context.Background(), 0, 0, 0, "", "", time.Time{}, time.Time{})
assert.ErrorIs(t, err, common.ErrDateUnset)
sharedtestvalues.SkipTestIfCredentialsUnset(t, bi)
_, err = bi.GetPledgeRateHistory(context.Background(), 0, 1, 5, "", "", time.Now().Add(-time.Hour*24*85),
time.Now())
assert.NoError(t, err)
}

func TestGetLoanRepayHistory(t *testing.T) {
func TestGetLoanHistory(t *testing.T) {
t.Parallel()
_, err := bi.GetLoanRepayHistory(context.Background(), 0, 0, 0, "", "", time.Time{}, time.Time{})
_, err := bi.GetLoanHistory(context.Background(), 0, 0, 0, "", "", "", time.Time{}, time.Time{})
assert.ErrorIs(t, err, common.ErrDateUnset)
sharedtestvalues.SkipTestIfCredentialsUnset(t, bi)
_, err = bi.GetLoanRepayHistory(context.Background(), 0, 1, 5, "", "", time.Now().Add(-time.Hour*24*85), time.Now())
_, err = bi.GetLoanHistory(context.Background(), 0, 1, 5, "", "", "", time.Now().Add(-time.Hour*24*85), time.Now())
assert.NoError(t, err)
}

func TestGetDebts(t *testing.T) {
t.Parallel()
sharedtestvalues.SkipTestIfCredentialsUnset(t, bi)
// If there aren't any debts to return information on, this will return the error "The data fetched by {user ID}
// is empty"
testGetNoArgs(t, bi.GetDebts)
}

func TestGetLiquidationRecords(t *testing.T) {
t.Parallel()
_, err := bi.GetLiquidationRecords(context.Background(), 0, 0, 0, "", "", "", time.Time{}, time.Time{})
assert.ErrorIs(t, err, common.ErrDateUnset)
sharedtestvalues.SkipTestIfCredentialsUnset(t, bi)
_, err = bi.GetLiquidationRecords(context.Background(), 0, 1, 5, "", "", "", time.Now().Add(-time.Hour*24*85),
time.Now())
assert.NoError(t, err)
}

func TestFetchTradablePairs(t *testing.T) {
t.Parallel()
_, err := bi.FetchTradablePairs(context.Background(), asset.Spot)
assert.NoError(t, err)
_, err = bi.FetchTradablePairs(context.Background(), asset.Margin)
assert.NoError(t, err)
}

Expand Down Expand Up @@ -2465,9 +2513,27 @@ func TestBatchCancelIsolatedOrders(t *testing.T) {
assert.NoError(t, err)
}

func TestRepayLoan(t *testing.T) {
// Not parallel due to a collision with ModifyPledgeRate
_, err := bi.RepayLoan(context.Background(), 0, 0, false, false)
assert.ErrorIs(t, err, errOrderIDEmpty)
_, err = bi.RepayLoan(context.Background(), 1, 0, false, false)
assert.ErrorIs(t, err, errAmountEmpty)
sharedtestvalues.SkipTestIfCredentialsUnset(t, bi, canManipulateRealOrders)
resp, err := bi.GetOngoingLoans(context.Background(), 0, "", "")
require.NoError(t, err)
if len(resp.Data) == 0 {
t.Skip(skipInsufficientOrders)
}
_, err = bi.RepayLoan(context.Background(), resp.Data[0].OrderID, testAmount, false, false)
assert.NoError(t, err)
_, err = bi.RepayLoan(context.Background(), resp.Data[0].OrderID, 0, true, true)
assert.NoError(t, err)
}

type getNoArgsResp interface {
*TimeResp | *P2PMerInfoResp | *ConvertCoinsResp | *BGBConvertCoinsResp | *VIPFeeRateResp | *SupCurrencyResp |
*RiskRateCross | *SavingsBalance | *SharkFinBalance
*RiskRateCross | *SavingsBalance | *SharkFinBalance | *DebtsResp
}

type getNoArgsAssertNotEmpty[G getNoArgsResp] func(context.Context) (G, error)
Expand Down
80 changes: 71 additions & 9 deletions exchanges/bitget/bitget_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2144,15 +2144,15 @@ type SharkFinSubDetail struct {
type LoanCurList struct {
Data struct {
LoanInfos []struct {
Coin string `json:"coin"`
HourRate7Day float64 `json:"hourRate7D,string"`
Rate7Day float64 `json:"rate7D,string"`
HourRate30Day float64 `json:"hourRate30D,string"`
Rate30Day float64 `json:"rate30D,string"`
MinUSDT float64 `json:"minUsdt,string"`
MaxUSDT float64 `json:"maxUsdt,string"`
Min float64 `json:"min,string"`
Max float64 `json:"max,string"`
Coin string `json:"coin"`
HourlyRate7Day float64 `json:"hourRate7D,string"`
Rate7Day float64 `json:"rate7D,string"`
HourlyRate30Day float64 `json:"hourRate30D,string"`
Rate30Day float64 `json:"rate30D,string"`
MinUSDT float64 `json:"minUsdt,string"`
MaxUSDT float64 `json:"maxUsdt,string"`
Min float64 `json:"min,string"`
Max float64 `json:"max,string"`
} `json:"loanInfos"`
PledgeInfos []struct {
Coin string `json:"coin"`
Expand Down Expand Up @@ -2231,3 +2231,65 @@ type ModPledgeResp struct {
AfterPledgeRate float64 `json:"afterPledgeRate,string"`
} `json:"data"`
}

// PledgeRateHist contains information on historical pledge rates
type PledgeRateHist struct {
Data []struct {
LoanCoin string `json:"loanCoin"`
PledgeCoin string `json:"pledgeCoin"`
OrderID int64 `json:"orderId,string"`
ReviseTime UnixTimestamp `json:"reviseTime"`
ReviseSide string `json:"reviseSide"`
ReviseAmount float64 `json:"reviseAmount,string"`
AfterPledgeRate float64 `json:"afterPledgeRate,string"`
BeforePledgeRate float64 `json:"beforePledgeRate,string"`
} `json:"data"`
}

// LoanHistory contains information on loans
type LoanHistory struct {
Data []struct {
OrderID int64 `json:"orderId,string"`
LoanCoin string `json:"loanCoin"`
PledgeCoin string `json:"pledgeCoin"`
InitialPledgeAmount float64 `json:"initPledgeAmount,string"`
InitialLoanAmount float64 `json:"initLoanAmount,string"`
HourlyRate float64 `json:"hourRate,string"`
Daily float64 `json:"daily,string"`
BorrowTime UnixTimestamp `json:"borrowTime"`
Status string `json:"status"`
} `json:"data"`
}

// CoinAm includes fields for coins, amounts, and amount-equivalents in USDT
type CoinAm struct {
Coin string `json:"coin"`
Amount float64 `json:"amount,string"`
AmountUSDT float64 `json:"amountUsdt,string"`
}

// DebtsResp contains information on debts
type DebtsResp struct {
Data struct {
PledgeInfos []CoinAm `json:"pledgeInfos"`
LoanInfos []CoinAm `json:"loanInfos"`
} `json:"data"`
}

// LiquidRecs contains information on liquidation records
type LiquidRecs struct {
Data []struct {
OrderID int64 `json:"orderId,string"`
LoanCoin string `json:"loanCoin"`
PledgeCoin string `json:"pledgeCoin"`
ReduceTime UnixTimestamp `json:"reduceTime"`
PledgeRate float64 `json:"pledgeRate,string"`
PledgePrice float64 `json:"pledgePrice,string"`
Status string `json:"status"`
PledgeAmount float64 `json:"pledgeAmount,string"`
ReduceFee string `json:"reduceFee"`
ResidueAmount float64 `json:"residueAmount,string"`
RunlockAmount float64 `json:"runlockAmount,string"`
RepayLoanAmount float64 `json:"repayLoanAmount,string"`
} `json:"data"`
}
34 changes: 32 additions & 2 deletions exchanges/bitget/bitget_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,38 @@ func (bi *Bitget) Setup(exch *config.Exchange) error {

// FetchTradablePairs returns a list of the exchanges tradable pairs
func (bi *Bitget) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) {

Check warning on line 161 in exchanges/bitget/bitget_wrapper.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
// Implement fetching the exchange available pairs if supported
return nil, nil
// This doesn't work; those endpoints only return currencies, not pairs
// switch a {
// case asset.Spot:
// resp, err := bi.GetCoinInfo(ctx, "")
// if err != nil {
// return nil, err
// }
// pairs := make(currency.Pairs, len(resp.Data))
// for x := range resp.Data {
// pair, err := currency.NewPairFromString(resp.Data[x].Coin)
// if err != nil {
// return nil, err
// }
// pairs[x] = pair
// }
// return pairs, nil
// case asset.Margin, asset.Futures:
// resp, err := bi.GetSupportedCurrencies(ctx)
// if err != nil {
// return nil, err
// }
// pairs := make(currency.Pairs, len(resp.Data))
// for x := range resp.Data {
// pair, err := currency.NewPairFromString(resp.Data[x].Symbol)
// if err != nil {
// return nil, err
// }
// pairs[x] = pair
// }
// return pairs, nil
// }
return nil, asset.ErrNotSupported
}

// UpdateTradablePairs updates the exchanges available pairs and stores
Expand Down

0 comments on commit 7904cde

Please sign in to comment.