diff --git a/exchanges/bitget/bitget.go b/exchanges/bitget/bitget.go index a58b84cf454..3861e15e4a7 100644 --- a/exchanges/bitget/bitget.go +++ b/exchanges/bitget/bitget.go @@ -178,6 +178,7 @@ const ( bitgetRedeemResult = "/redeem-result" bitgetSharkFin = "sharkfin" bitgetOngoingOrders = "/ongoing-orders" + bitgetRevisePledge = "/revise-pledge" // Errors errUnknownEndpointLimit = "unknown endpoint limit %v" @@ -249,6 +250,7 @@ var ( errTermEmpty = errors.New("term cannot be empty") errCollateralAmountEmpty = errors.New("collateralAmount cannot be empty") errCollateralLoanMutex = errors.New("exactly one of collateralAmount and loanAmount must be set") + errReviseTypeEmpty = errors.New("reviseType cannot be empty") ) // QueryAnnouncement returns announcements from the exchange, filtered by type and time @@ -4117,6 +4119,55 @@ func (bi *Bitget) RepayLoan(ctx context.Context, orderID int64, amount float64, &resp) } +// GetLoanRepayHistory returns the repayment records for a loan +func (bi *Bitget) GetLoanRepayHistory(ctx context.Context, orderID, pagination, limit int64, loanCoin, pledgeCoin string, startTime, endTime time.Time) (*RepayRecords, 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) + 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 + bitgetRepayHistory + var resp *RepayRecords + return resp, bi.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, Rate10, http.MethodGet, path, params.Values, + nil, &resp) +} + +// 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) { + if orderID == 0 { + return nil, errOrderIDEmpty + } + if amoutn == 0 { + return nil, errAmountEmpty + } + if pledgeCoin == "" { + return nil, errCollateralCoinEmpty + } + if reviseType == "" { + return nil, errReviseTypeEmpty + } + req := map[string]interface{}{ + "orderId": orderID, + "amount": strconv.FormatFloat(amoutn, 'f', -1, 64), + "pledgeCoin": pledgeCoin, + "reviseType": reviseType, + } + path := bitgetEarn + bitgetLoan + bitgetRevisePledge + var resp *ModPledgeResp + return resp, bi.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, Rate10, http.MethodPost, path, nil, req, + &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) diff --git a/exchanges/bitget/bitget_test.go b/exchanges/bitget/bitget_test.go index a12a16cf5de..3783c3e4d59 100644 --- a/exchanges/bitget/bitget_test.go +++ b/exchanges/bitget/bitget_test.go @@ -2294,6 +2294,35 @@ func TestGetOngoingLoans(t *testing.T) { if len(resp.Data) == 0 { t.Skip(skipInsufficientOrders) } + _, err = bi.GetOngoingLoans(context.Background(), resp.Data[0].OrderID, "", "") + assert.NoError(t, err) +} + +func TestRepayLoan(t *testing.T) { + t.Parallel() + _, 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) +} + +func TestGetLoanRepayHistory(t *testing.T) { + t.Parallel() + _, 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 TestCommitConversion(t *testing.T) { diff --git a/exchanges/bitget/bitget_types.go b/exchanges/bitget/bitget_types.go index d5a51cf147f..624367db352 100644 --- a/exchanges/bitget/bitget_types.go +++ b/exchanges/bitget/bitget_types.go @@ -2208,3 +2208,26 @@ type RepayResp struct { RepayUnlockAmount float64 `json:"repayUnlockAmount,string"` } `json:"data"` } + +// RepayRecords contains information on repayment records +type RepayRecords struct { + Data []struct { + OrderID int64 `json:"orderId,string"` + LoanCoin string `json:"loanCoin"` + PledgeCoin string `json:"pledgeCoin"` + RepayAmount float64 `json:"repayAmount,string"` + PayInterest float64 `json:"payInterest,string"` + RepayLoanAmount float64 `json:"repayLoanAmount,string"` + RepayUnlockAmount float64 `json:"repayUnlockAmount,string"` + RepayTime UnixTimestamp `json:"repayTime"` + } `json:"data"` +} + +// ModPledgeResp contains information on a pledge modification +type ModPledgeResp struct { + Data struct { + LoanCoin string `json:"loanCoin"` + PledgeCoin string `json:"pledgeCoin"` + AfterPledgeRate float64 `json:"afterPledgeRate,string"` + } `json:"data"` +}