diff --git a/cmd/ccy-cli/balance.go b/cmd/ccy-cli/balance.go index 355e3ae..2a6d818 100644 --- a/cmd/ccy-cli/balance.go +++ b/cmd/ccy-cli/balance.go @@ -9,7 +9,7 @@ import ( "github.com/dasbd72/go-exchange-sdk/config" "github.com/dasbd72/go-exchange-sdk/manager" "github.com/dasbd72/go-exchange-sdk/max" - "github.com/dasbd72/go-exchange-sdk/okx" + okxRest "github.com/dasbd72/go-exchange-sdk/okx/pkg/rest" "github.com/spf13/cobra" ) @@ -33,7 +33,7 @@ func Balance(cmd *cobra.Command, args []string) error { c := manager.Client_builder{ BinanceClient: binanceSpot.NewClient(cfg.BinanceApiKey, cfg.BinanceApiSecret), - OkxClient: okx.NewClient(cfg.OKXApiKey, cfg.OKXApiSecret, cfg.OKXPassphrase), + OkxClient: okxRest.NewClient(cfg.OKXApiKey, cfg.OKXApiSecret, cfg.OKXPassphrase), BitfinexRestClient: bitfinexRest.NewClient(cfg.BitfinexApiKey, cfg.BitfinexApiSecret), }.Build() diff --git a/cmd/ccy-cli/main.go b/cmd/ccy-cli/main.go index e2de063..602865e 100644 --- a/cmd/ccy-cli/main.go +++ b/cmd/ccy-cli/main.go @@ -21,11 +21,6 @@ func main() { Use: "experimental", Short: "Experimental commands", } - okxCmd := &cobra.Command{ - Use: "okx", - Short: "OKX commands", - Run: OKX, - } maxCmd := &cobra.Command{ Use: "max", Short: "Max commands", @@ -37,7 +32,6 @@ func main() { RunE: Balance, } root.PersistentFlags().BoolVarP(&useLog, "log", "l", false, "Use log") - root.AddCommand(okxCmd) root.AddCommand(maxCmd) root.AddCommand(balanceCmd) root.Execute() diff --git a/cmd/ccy-cli/okx.go b/cmd/ccy-cli/okx.go deleted file mode 100644 index 0bcf9a0..0000000 --- a/cmd/ccy-cli/okx.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "context" - "encoding/json" - "log" - "os" - - "github.com/dasbd72/go-exchange-sdk/okx" - "github.com/spf13/cobra" -) - -func OKX(cmd *cobra.Command, args []string) { - ctx := context.Background() - // Create a new OKX client - c := okx.NewClient( - os.Getenv("OKX_API_KEY"), - os.Getenv("OKX_API_SECRET"), - os.Getenv("OKX_PASSPHRASE"), - ) - - // Start testing - // data, err := c.GetBalance(ctx, &okx.GetBalanceRequest{ - // Ccy: "BTC", - // }) - // data, err := c.GetTicker(ctx, &okx.GetTickerRequest{ - // InstID: "BTC-USDT", - // }) - // data, err := c.GetTickers(ctx, &okx.GetTickersRequest{ - // InstType: "SPOT", - // }) - // data, err := c.GetFundingBalances(ctx, &okx.GetFundingBalancesRequest{}) - // data, err := c.GetSavingBalance(ctx, &okx.GetSavingBalanceRequest{}) - // data, err := c.GetETHStakingBalance(ctx, &okx.GetETHStakingBalanceRequest{}) - // data, err := c.GetEarnOffers(ctx, &okx.GetEarnOffersRequest{}) - // data, err := c.GetActiveEarnOrders(ctx, &okx.GetActiveEarnOrdersRequest{}) - data, err := c.GetLendingHistory(ctx, okx.NewGetLendingHistoryRequest()) - if err != nil { - log.Fatal(err) - } - // log.Println(data) - b, err := json.MarshalIndent(data, "", " ") - if err != nil { - log.Fatal(err) - } - log.Println(string(b)) -} diff --git a/manager/balance.go b/manager/balance.go index 0f9b211..6d07421 100644 --- a/manager/balance.go +++ b/manager/balance.go @@ -2,10 +2,11 @@ package manager import ( "context" + "fmt" binanceModels "github.com/dasbd72/go-exchange-sdk/binance/pkg/models" "github.com/dasbd72/go-exchange-sdk/max" - "github.com/dasbd72/go-exchange-sdk/okx" + okxModels "github.com/dasbd72/go-exchange-sdk/okx/pkg/models" ) type ( @@ -43,6 +44,7 @@ func (c *Client) GetBalance(ctx context.Context) (*Balance, error) { btcPrice := averagePrice.Price.Float64() totalBalanceUsdt += sum * btcPrice + fmt.Println("Binance balance: ", sum*btcPrice) return nil }, func() error { @@ -52,22 +54,32 @@ func (c *Client) GetBalance(ctx context.Context) (*Balance, error) { } sum := 0.0 // Get balance from wallet - wallet, err := c.okxClient.GetBalance(ctx, okx.NewGetBalanceRequest()) + wallet, err := c.okxClient.GetBalance(ctx, okxModels.NewGetBalanceRequest()) if err != nil { return err } for _, w := range wallet.Balances { - sum += w.TotalEq.Float64() + for _, detail := range w.Details { + price := 1.0 + if detail.Ccy != "USDT" { + ticker, err := c.okxClient.GetTicker(ctx, okxModels.NewGetTickerRequest(detail.Ccy+"-USDT")) + if err != nil { + return err + } + price = ticker.Tickers[0].Last.Float64() + } + sum += detail.Eq.Float64() * price + } } // Get balance from funding - funding, err := c.okxClient.GetFundingBalances(ctx, okx.NewGetFundingBalancesRequest()) + funding, err := c.okxClient.GetFundingBalances(ctx, okxModels.NewGetFundingBalancesRequest()) if err != nil { return err } for _, f := range funding.Balances { price := 1.0 if f.Ccy != "USDT" { - ticker, err := c.okxClient.GetTicker(ctx, okx.NewGetTickerRequest(f.Ccy+"-USDT")) + ticker, err := c.okxClient.GetTicker(ctx, okxModels.NewGetTickerRequest(f.Ccy+"-USDT")) if err != nil { return err } @@ -76,14 +88,14 @@ func (c *Client) GetBalance(ctx context.Context) (*Balance, error) { sum += f.Bal.Float64() * price } // Get balance from saving - savings, err := c.okxClient.GetSavingBalance(ctx, okx.NewGetSavingBalanceRequest()) + savings, err := c.okxClient.GetSavingBalance(ctx, okxModels.NewGetSavingBalanceRequest()) if err != nil { return err } for _, s := range savings.Balances { price := 1.0 if s.Ccy != "USDT" { - ticker, err := c.okxClient.GetTicker(ctx, okx.NewGetTickerRequest(s.Ccy+"-USDT")) + ticker, err := c.okxClient.GetTicker(ctx, okxModels.NewGetTickerRequest(s.Ccy+"-USDT")) if err != nil { return err } @@ -92,6 +104,7 @@ func (c *Client) GetBalance(ctx context.Context) (*Balance, error) { sum += s.Amt.Float64() * price } totalBalanceUsdt += sum + fmt.Println("OKX balance: ", sum) return nil }, func() error { @@ -112,6 +125,7 @@ func (c *Client) GetBalance(ctx context.Context) (*Balance, error) { } totalBalanceUsdt += sum + fmt.Println("Bitfinex balance: ", sum) return nil }, func() error { diff --git a/manager/client.go b/manager/client.go index 671df80..683f7c8 100644 --- a/manager/client.go +++ b/manager/client.go @@ -3,18 +3,18 @@ package manager import ( binanceRest "github.com/dasbd72/go-exchange-sdk/binance/pkg/spot" bitfinexRest "github.com/dasbd72/go-exchange-sdk/bitfinex/pkg/rest" - "github.com/dasbd72/go-exchange-sdk/okx" + okxRest "github.com/dasbd72/go-exchange-sdk/okx/pkg/rest" ) type Client struct { binanceClient *binanceRest.Client - okxClient *okx.Client + okxClient *okxRest.Client bitfinexRestClient *bitfinexRest.Client } type Client_builder struct { BinanceClient *binanceRest.Client - OkxClient *okx.Client + OkxClient *okxRest.Client BitfinexRestClient *bitfinexRest.Client } diff --git a/okx/example/rest/financial_service/main.go b/okx/example/rest/financial_service/main.go new file mode 100644 index 0000000..ab2d229 --- /dev/null +++ b/okx/example/rest/financial_service/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "context" + "encoding/json" + + "github.com/dasbd72/go-exchange-sdk/config" + "github.com/dasbd72/go-exchange-sdk/okx/pkg/models" + "github.com/dasbd72/go-exchange-sdk/okx/pkg/rest" +) + +func main() { + cfg, err := config.Load() + if err != nil { + panic(err) + } + + ctx := context.Background() + c := rest.NewClient(cfg.OKXApiKey, cfg.OKXApiSecret, cfg.OKXPassphrase) + + { + res, err := c.GetSavingBalance(ctx, models.NewGetSavingBalanceRequest()) + if err != nil { + panic(err) + } + b, err := json.MarshalIndent(res, "", " ") + if err != nil { + panic(err) + } + println(string(b)) + } +} diff --git a/okx/example/rest/funding_service/main.go b/okx/example/rest/funding_service/main.go new file mode 100644 index 0000000..8375e5a --- /dev/null +++ b/okx/example/rest/funding_service/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "context" + "encoding/json" + + "github.com/dasbd72/go-exchange-sdk/config" + "github.com/dasbd72/go-exchange-sdk/okx/pkg/models" + "github.com/dasbd72/go-exchange-sdk/okx/pkg/rest" +) + +func main() { + cfg, err := config.Load() + if err != nil { + panic(err) + } + + ctx := context.Background() + c := rest.NewClient(cfg.OKXApiKey, cfg.OKXApiSecret, cfg.OKXPassphrase) + + { + res, err := c.GetFundingBalances(ctx, models.NewGetFundingBalancesRequest()) + if err != nil { + panic(err) + } + b, err := json.MarshalIndent(res, "", " ") + if err != nil { + panic(err) + } + println(string(b)) + } +} diff --git a/okx/example/rest/trading_service/main.go b/okx/example/rest/trading_service/main.go new file mode 100644 index 0000000..0c160c3 --- /dev/null +++ b/okx/example/rest/trading_service/main.go @@ -0,0 +1,32 @@ +package main + +import ( + "context" + "encoding/json" + + "github.com/dasbd72/go-exchange-sdk/config" + "github.com/dasbd72/go-exchange-sdk/okx/pkg/models" + "github.com/dasbd72/go-exchange-sdk/okx/pkg/rest" +) + +func main() { + cfg, err := config.Load() + if err != nil { + panic(err) + } + + ctx := context.Background() + c := rest.NewClient(cfg.OKXApiKey, cfg.OKXApiSecret, cfg.OKXPassphrase) + + { + res, err := c.GetBalance(ctx, models.NewGetBalanceRequest()) + if err != nil { + panic(err) + } + b, err := json.MarshalIndent(res, "", " ") + if err != nil { + panic(err) + } + println(string(b)) + } +} diff --git a/okx/financial_rest_service.go b/okx/financial_rest_service.go deleted file mode 100644 index 8b2c2e2..0000000 --- a/okx/financial_rest_service.go +++ /dev/null @@ -1,294 +0,0 @@ -package okx - -import ( - "context" - "encoding/json" - "net/http" -) - -type ( - GetEarnOffersRequest struct { - params map[string]interface{} - } - - GetEarnOffersResponse struct { - BasicResponse - Offers []struct { - Ccy string `json:"ccy"` - ProductId JSONInt64 `json:"productId"` - Protocol string `json:"protocol"` - ProtocolType string `json:"protocolType"` - Term JSONInt64 `json:"term"` - Apy JSONFloat64 `json:"apy"` - EarlyRedeem bool `json:"earlyRedeem"` - InvestData []struct { - Ccy string `json:"ccy"` - Bal JSONFloat64 `json:"bal"` - MinAmt JSONFloat64 `json:"minAmt"` - MaxAmt JSONFloat64 `json:"maxAmt"` - } `json:"investData"` - EarningData []struct { - Ccy string `json:"ccy"` - EarningType JSONInt64 `json:"earningType"` - } `json:"earningData"` - State string `json:"state"` - } `json:"data,omitempty"` - } - - GetActiveEarnOrdersRequest struct { - params map[string]interface{} - } - - GetActiveEarnOrdersResponse struct { - BasicResponse - Orders []struct { - Ccy string `json:"ccy"` - OrdId JSONInt64 `json:"ordId"` - ProductId JSONInt64 `json:"productId"` - State string `json:"state"` - Protocol string `json:"protocol"` - ProtocolType string `json:"protocolType"` - Term JSONInt64 `json:"term"` - Apy JSONFloat64 `json:"apy"` - InvestData []struct { - Ccy string `json:"ccy"` - Amt JSONFloat64 `json:"amt"` - } `json:"investData"` - EarningData []struct { - Ccy string `json:"ccy"` - EarningType JSONInt64 `json:"earningType"` - Earnings JSONFloat64 `json:"earnings"` - } `json:"earningData"` - PurchasedTime JSONTime `json:"purchasedTime"` - EstSettlementTime JSONTime `json:"estSettlementTime,omitempty"` - CancelRedemptionDeadline JSONTime `json:"cancelRedemptionDeadline,omitempty"` - Tag string `json:"tag,omitempty"` - } `json:"data,omitempty"` - } - - GetETHStakingBalanceResponse struct { - BasicResponse - Balances []struct { - Ccy string `json:"ccy"` - Amt JSONFloat64 `json:"amt"` - LatestInterestAccrual JSONFloat64 `json:"latestInterestAccrual"` - TotalInterestAccrual JSONFloat64 `json:"totalInterestAccrual"` - Ts JSONTime `json:"ts"` - } `json:"data,omitempty"` - } - - GetSavingBalanceRequest struct { - params map[string]interface{} - } - - GetSavingBalanceResponse struct { - BasicResponse - Balances []struct { - Ccy string `json:"ccy"` - Amt JSONFloat64 `json:"amt"` - Earnings JSONFloat64 `json:"earnings"` - Rate JSONFloat64 `json:"rate"` - LoanAmt JSONFloat64 `json:"loanAmt"` - PendingAmt JSONFloat64 `json:"pendingAmt"` - RedemptAmt JSONFloat64 `json:"redemptAmt,omitempty"` // Deprecated - } `json:"data,omitempty"` - } - - GetLendingHistoryRequest struct { - params map[string]interface{} - } - - GetLendingHistoryResponse struct { - BasicResponse - Records []struct { - Ccy string `json:"ccy"` - Amt JSONFloat64 `json:"amt"` - Earnings JSONFloat64 `json:"earnings"` - Rate JSONFloat64 `json:"rate"` - Ts JSONTime `json:"ts"` - } `json:"data,omitempty"` - } -) - -func NewGetEarnOffersRequest() *GetEarnOffersRequest { - return &GetEarnOffersRequest{ - params: map[string]interface{}{}, - } -} - -func (r *GetEarnOffersRequest) ProductId(productId string) *GetEarnOffersRequest { - r.params["productId"] = productId - return r -} - -func (r *GetEarnOffersRequest) ProtocolType(protocolType string) *GetEarnOffersRequest { - r.params["protocolType"] = protocolType - return r -} - -func (r *GetEarnOffersRequest) Ccy(ccy string) *GetEarnOffersRequest { - r.params["ccy"] = ccy - return r -} - -// GetEarnOffers get the available earn offers -func (c *Client) GetEarnOffers(ctx context.Context, req *GetEarnOffersRequest, opts ...RequestOption) (*GetEarnOffersResponse, error) { - res, err := c.CallAPI(ctx, Request_builder{ - Method: http.MethodGet, - Endpoint: "/api/v5/finance/staking-defi/offers", - SecType: SecTypePrivate, - Params: req.params, - }.Build(), opts...) - if err != nil { - return nil, err - } - data := &GetEarnOffersResponse{} - err = json.Unmarshal(res, data) - if err != nil { - return nil, err - } - return data, nil -} - -func NewGetActiveEarnOrdersRequest() *GetActiveEarnOrdersRequest { - return &GetActiveEarnOrdersRequest{ - params: map[string]interface{}{}, - } -} - -func (r *GetActiveEarnOrdersRequest) ProductId(productId string) *GetActiveEarnOrdersRequest { - r.params["productId"] = productId - return r -} - -func (r *GetActiveEarnOrdersRequest) ProtocolType(protocolType string) *GetActiveEarnOrdersRequest { - r.params["protocolType"] = protocolType - return r -} - -func (r *GetActiveEarnOrdersRequest) Ccy(ccy string) *GetActiveEarnOrdersRequest { - r.params["ccy"] = ccy - return r -} - -func (r *GetActiveEarnOrdersRequest) State(state JSONInt64) *GetActiveEarnOrdersRequest { - r.params["state"] = state - return r -} - -// GetActiveEarnOrders get the active earn orders -func (c *Client) GetActiveEarnOrders(ctx context.Context, req *GetActiveEarnOrdersRequest, opts ...RequestOption) (*GetActiveEarnOrdersResponse, error) { - res, err := c.CallAPI(ctx, Request_builder{ - Method: http.MethodGet, - Endpoint: "/api/v5/finance/staking-defi/orders-active", - SecType: SecTypePrivate, - Params: req.params, - }.Build(), opts...) - if err != nil { - return nil, err - } - data := &GetActiveEarnOrdersResponse{} - err = json.Unmarshal(res, data) - if err != nil { - return nil, err - } - return data, nil -} - -// GetETHStakingBalance get balances in the ETH staking account -func (c *Client) GetETHStakingBalance(ctx context.Context, opts ...RequestOption) (*GetETHStakingBalanceResponse, error) { - res, err := c.CallAPI(ctx, Request_builder{ - Method: http.MethodGet, - Endpoint: "/api/v5/finance/staking-defi/eth/balance", - SecType: SecTypePrivate, - }.Build(), opts...) - if err != nil { - return nil, err - } - data := &GetETHStakingBalanceResponse{} - err = json.Unmarshal(res, data) - if err != nil { - return nil, err - } - return data, nil -} - -func NewGetSavingBalanceRequest() *GetSavingBalanceRequest { - return &GetSavingBalanceRequest{ - params: map[string]interface{}{}, - } -} - -func (r *GetSavingBalanceRequest) Ccy(ccy string) *GetSavingBalanceRequest { - r.params["ccy"] = ccy - return r -} - -// GetSavingBalance get balances in the saving account -func (c *Client) GetSavingBalance(ctx context.Context, req *GetSavingBalanceRequest, opts ...RequestOption) (*GetSavingBalanceResponse, error) { - res, err := c.CallAPI(ctx, Request_builder{ - Method: http.MethodGet, - Endpoint: "/api/v5/finance/savings/balance", - SecType: SecTypePrivate, - Params: req.params, - }.Build(), opts...) - if err != nil { - return nil, err - } - data := &GetSavingBalanceResponse{} - err = json.Unmarshal(res, data) - if err != nil { - return nil, err - } - return data, nil -} - -func NewGetLendingHistoryRequest() *GetLendingHistoryRequest { - return &GetLendingHistoryRequest{ - params: map[string]interface{}{}, - } -} - -func (r *GetLendingHistoryRequest) Ccy(ccy string) *GetLendingHistoryRequest { - r.params["ccy"] = ccy - return r -} - -// After sets pagination of data to return records earlier than the requested ts, -// Unix timestamp format in milliseconds, e.g. 1597026383085 -func (r *GetLendingHistoryRequest) After(after int64) *GetLendingHistoryRequest { - r.params["after"] = after - return r -} - -// Before sets pagination of data to return records newer than the requested ts, -// Unix timestamp format in milliseconds, e.g. 1597026383085 -func (r *GetLendingHistoryRequest) Before(before int64) *GetLendingHistoryRequest { - r.params["before"] = before - return r -} - -// Limit sets number of results per request. The maximum is 100. The default is 100. -func (r *GetLendingHistoryRequest) Limit(limit int64) *GetLendingHistoryRequest { - r.params["limit"] = limit - return r -} - -// GetLendingHistory get the lending history -func (c *Client) GetLendingHistory(ctx context.Context, req *GetLendingHistoryRequest, opts ...RequestOption) (*GetLendingHistoryResponse, error) { - res, err := c.CallAPI(ctx, Request_builder{ - Method: http.MethodGet, - Endpoint: "/api/v5/finance/savings/lending-history", - SecType: SecTypePrivate, - Params: req.params, - }.Build(), opts...) - if err != nil { - return nil, err - } - data := &GetLendingHistoryResponse{} - err = json.Unmarshal(res, data) - if err != nil { - return nil, err - } - return data, nil -} diff --git a/okx/funding_rest_service.go b/okx/funding_rest_service.go deleted file mode 100644 index 6b3f5d3..0000000 --- a/okx/funding_rest_service.go +++ /dev/null @@ -1,53 +0,0 @@ -package okx - -import ( - "context" - "encoding/json" - "net/http" -) - -type ( - GetFundingBalancesRequest struct { - params map[string]interface{} - } - - GetFundingBalancesResponse struct { - BasicResponse - Balances []struct { - Ccy string `json:"ccy"` - Bal JSONFloat64 `json:"bal"` - FrozenBal JSONFloat64 `json:"frozenBal"` - AvailBal JSONFloat64 `json:"availBal"` - } `json:"data,omitempty"` - } -) - -func NewGetFundingBalancesRequest() *GetFundingBalancesRequest { - return &GetFundingBalancesRequest{ - params: make(map[string]interface{}), - } -} - -func (r *GetFundingBalancesRequest) Ccy(ccy string) *GetFundingBalancesRequest { - r.params["ccy"] = ccy - return r -} - -// GetFundingBalances get balances in the funding account -func (c *Client) GetFundingBalances(ctx context.Context, req *GetFundingBalancesRequest, opts ...RequestOption) (*GetFundingBalancesResponse, error) { - res, err := c.CallAPI(ctx, Request_builder{ - Method: http.MethodGet, - Endpoint: "/api/v5/asset/balances", - SecType: SecTypePrivate, - Params: req.params, - }.Build(), opts...) - if err != nil { - return nil, err - } - data := &GetFundingBalancesResponse{} - err = json.Unmarshal(res, data) - if err != nil { - return nil, err - } - return data, nil -} diff --git a/okx/market_rest_service.go b/okx/market_rest_service.go deleted file mode 100644 index 0d080af..0000000 --- a/okx/market_rest_service.go +++ /dev/null @@ -1,110 +0,0 @@ -package okx - -import ( - "context" - "encoding/json" - "net/http" -) - -type ( - Tickers struct { - InstID string `json:"instId"` - InstType string `json:"instType"` - Last JSONFloat64 `json:"last"` - LastSz JSONFloat64 `json:"lastSz"` - AskPx JSONFloat64 `json:"askPx"` - AskSz JSONFloat64 `json:"askSz"` - BidPx JSONFloat64 `json:"bidPx"` - BidSz JSONFloat64 `json:"bidSz"` - Open24h JSONFloat64 `json:"open24h"` - High24h JSONFloat64 `json:"high24h"` - Low24h JSONFloat64 `json:"low24h"` - VolCcy24h JSONFloat64 `json:"volCcy24h"` - Vol24h JSONFloat64 `json:"vol24h"` - SodUtc0 JSONFloat64 `json:"sodUtc0"` - SodUtc8 JSONFloat64 `json:"sodUtc8"` - TS JSONTime `json:"ts"` - } - - GetTickersRequest struct { - params map[string]interface{} - } - - GetTickersResponse struct { - BasicResponse - Tickers []Tickers `json:"data,omitempty"` - } - - GetTickerRequest struct { - params map[string]interface{} - } - - GetTickerResponse struct { - BasicResponse - Tickers []Tickers `json:"data,omitempty"` - } -) - -func NewGetTickersRequest(instType string) *GetTickersRequest { - return &GetTickersRequest{ - params: map[string]interface{}{ - "instType": instType, - }, - } -} - -func (r *GetTickersRequest) Uly(uly string) *GetTickersRequest { - r.params["uly"] = uly - return r -} - -func (r *GetTickersRequest) InstFamily(instFamily string) *GetTickersRequest { - r.params["instFamily"] = instFamily - return r -} - -// GetTickers get tickers of instruments -func (c *Client) GetTickers(ctx context.Context, req *GetTickersRequest, opts ...RequestOption) (*GetTickersResponse, error) { - res, err := c.CallAPI(ctx, Request_builder{ - Method: http.MethodGet, - Endpoint: "/api/v5/market/tickers", - SecType: SecTypePublic, - Params: req.params, - }.Build(), opts...) - if err != nil { - return nil, err - } - data := &GetTickersResponse{} - err = json.Unmarshal(res, data) - if err != nil { - return nil, err - } - return data, nil -} - -func NewGetTickerRequest(instID string) *GetTickerRequest { - return &GetTickerRequest{ - params: map[string]interface{}{ - "instId": instID, - }, - } -} - -// GetTicker get ticker of instrument -func (c *Client) GetTicker(ctx context.Context, req *GetTickerRequest, opts ...RequestOption) (*GetTickerResponse, error) { - res, err := c.CallAPI(ctx, Request_builder{ - Method: http.MethodGet, - Endpoint: "/api/v5/market/ticker", - SecType: SecTypePublic, - Params: req.params, - }.Build(), opts...) - if err != nil { - return nil, err - } - data := &GetTickerResponse{} - err = json.Unmarshal(res, data) - if err != nil { - return nil, err - } - return data, nil -} diff --git a/okx/definition.go b/okx/pkg/cast/cast.go similarity index 92% rename from okx/definition.go rename to okx/pkg/cast/cast.go index 5b62683..e6609f5 100644 --- a/okx/definition.go +++ b/okx/pkg/cast/cast.go @@ -1,4 +1,4 @@ -package okx +package cast import ( "strconv" @@ -10,11 +10,6 @@ type ( JSONFloat64 float64 JSONInt64 int64 JSONTime time.Time - - BasicResponse struct { - Code JSONInt64 `json:"code"` - Msg string `json:"msg"` - } ) func (t *JSONFloat64) Float64() float64 { return float64(*t) } diff --git a/okx/definition_test.go b/okx/pkg/cast/cast_test.go similarity index 99% rename from okx/definition_test.go rename to okx/pkg/cast/cast_test.go index ee8b213..a97217b 100644 --- a/okx/definition_test.go +++ b/okx/pkg/cast/cast_test.go @@ -1,4 +1,4 @@ -package okx +package cast import ( "strconv" diff --git a/okx/pkg/models/common.go b/okx/pkg/models/common.go new file mode 100644 index 0000000..c07e848 --- /dev/null +++ b/okx/pkg/models/common.go @@ -0,0 +1,8 @@ +package models + +import "github.com/dasbd72/go-exchange-sdk/okx/pkg/cast" + +type BasicResponse struct { + Code cast.JSONInt64 `json:"code"` + Msg string `json:"msg"` +} diff --git a/okx/pkg/models/financial_rest.go b/okx/pkg/models/financial_rest.go new file mode 100644 index 0000000..b2375d5 --- /dev/null +++ b/okx/pkg/models/financial_rest.go @@ -0,0 +1,212 @@ +package models + +import "github.com/dasbd72/go-exchange-sdk/okx/pkg/cast" + +type ( + GetEarnOffersRequest struct { + params map[string]interface{} + } + + GetEarnOffersResponse struct { + BasicResponse + Offers []struct { + Ccy string `json:"ccy"` + ProductId cast.JSONInt64 `json:"productId"` + Protocol string `json:"protocol"` + ProtocolType string `json:"protocolType"` + Term cast.JSONInt64 `json:"term"` + Apy cast.JSONFloat64 `json:"apy"` + EarlyRedeem bool `json:"earlyRedeem"` + InvestData []struct { + Ccy string `json:"ccy"` + Bal cast.JSONFloat64 `json:"bal"` + MinAmt cast.JSONFloat64 `json:"minAmt"` + MaxAmt cast.JSONFloat64 `json:"maxAmt"` + } `json:"investData"` + EarningData []struct { + Ccy string `json:"ccy"` + EarningType cast.JSONInt64 `json:"earningType"` + } `json:"earningData"` + State string `json:"state"` + } `json:"data,omitempty"` + } + + GetActiveEarnOrdersRequest struct { + params map[string]interface{} + } + + GetActiveEarnOrdersResponse struct { + BasicResponse + Orders []struct { + Ccy string `json:"ccy"` + OrdId cast.JSONInt64 `json:"ordId"` + ProductId cast.JSONInt64 `json:"productId"` + State string `json:"state"` + Protocol string `json:"protocol"` + ProtocolType string `json:"protocolType"` + Term cast.JSONInt64 `json:"term"` + Apy cast.JSONFloat64 `json:"apy"` + InvestData []struct { + Ccy string `json:"ccy"` + Amt cast.JSONFloat64 `json:"amt"` + } `json:"investData"` + EarningData []struct { + Ccy string `json:"ccy"` + EarningType cast.JSONInt64 `json:"earningType"` + Earnings cast.JSONFloat64 `json:"earnings"` + } `json:"earningData"` + PurchasedTime cast.JSONTime `json:"purchasedTime"` + EstSettlementTime cast.JSONTime `json:"estSettlementTime,omitempty"` + CancelRedemptionDeadline cast.JSONTime `json:"cancelRedemptionDeadline,omitempty"` + Tag string `json:"tag,omitempty"` + } `json:"data,omitempty"` + } + + GetETHStakingBalanceResponse struct { + BasicResponse + Balances []struct { + Ccy string `json:"ccy"` + Amt cast.JSONFloat64 `json:"amt"` + LatestInterestAccrual cast.JSONFloat64 `json:"latestInterestAccrual"` + TotalInterestAccrual cast.JSONFloat64 `json:"totalInterestAccrual"` + Ts cast.JSONTime `json:"ts"` + } `json:"data,omitempty"` + } + + GetSavingBalanceRequest struct { + params map[string]interface{} + } + + GetSavingBalanceResponse struct { + BasicResponse + Balances []struct { + Ccy string `json:"ccy"` + Amt cast.JSONFloat64 `json:"amt"` + Earnings cast.JSONFloat64 `json:"earnings"` + Rate cast.JSONFloat64 `json:"rate"` + LoanAmt cast.JSONFloat64 `json:"loanAmt"` + PendingAmt cast.JSONFloat64 `json:"pendingAmt"` + RedemptAmt cast.JSONFloat64 `json:"redemptAmt,omitempty"` // Deprecated + } `json:"data,omitempty"` + } + + GetLendingHistoryRequest struct { + params map[string]interface{} + } + + GetLendingHistoryResponse struct { + BasicResponse + Records []struct { + Ccy string `json:"ccy"` + Amt cast.JSONFloat64 `json:"amt"` + Earnings cast.JSONFloat64 `json:"earnings"` + Rate cast.JSONFloat64 `json:"rate"` + Ts cast.JSONTime `json:"ts"` + } `json:"data,omitempty"` + } +) + +func NewGetEarnOffersRequest() *GetEarnOffersRequest { + return &GetEarnOffersRequest{ + params: map[string]interface{}{}, + } +} + +func (r *GetEarnOffersRequest) ProductId(productId string) *GetEarnOffersRequest { + r.params["productId"] = productId + return r +} + +func (r *GetEarnOffersRequest) ProtocolType(protocolType string) *GetEarnOffersRequest { + r.params["protocolType"] = protocolType + return r +} + +func (r *GetEarnOffersRequest) Ccy(ccy string) *GetEarnOffersRequest { + r.params["ccy"] = ccy + return r +} + +func (r *GetEarnOffersRequest) Params() map[string]interface{} { + return r.params +} + +func NewGetActiveEarnOrdersRequest() *GetActiveEarnOrdersRequest { + return &GetActiveEarnOrdersRequest{ + params: map[string]interface{}{}, + } +} + +func (r *GetActiveEarnOrdersRequest) ProductId(productId string) *GetActiveEarnOrdersRequest { + r.params["productId"] = productId + return r +} + +func (r *GetActiveEarnOrdersRequest) ProtocolType(protocolType string) *GetActiveEarnOrdersRequest { + r.params["protocolType"] = protocolType + return r +} + +func (r *GetActiveEarnOrdersRequest) Ccy(ccy string) *GetActiveEarnOrdersRequest { + r.params["ccy"] = ccy + return r +} + +func (r *GetActiveEarnOrdersRequest) State(state cast.JSONInt64) *GetActiveEarnOrdersRequest { + r.params["state"] = state + return r +} + +func (r *GetActiveEarnOrdersRequest) Params() map[string]interface{} { + return r.params +} + +func NewGetSavingBalanceRequest() *GetSavingBalanceRequest { + return &GetSavingBalanceRequest{ + params: map[string]interface{}{}, + } +} + +func (r *GetSavingBalanceRequest) Ccy(ccy string) *GetSavingBalanceRequest { + r.params["ccy"] = ccy + return r +} + +func (r *GetSavingBalanceRequest) Params() map[string]interface{} { + return r.params +} + +func NewGetLendingHistoryRequest() *GetLendingHistoryRequest { + return &GetLendingHistoryRequest{ + params: map[string]interface{}{}, + } +} + +func (r *GetLendingHistoryRequest) Ccy(ccy string) *GetLendingHistoryRequest { + r.params["ccy"] = ccy + return r +} + +// After sets pagination of data to return records earlier than the requested ts, +// Unix timestamp format in milliseconds, e.g. 1597026383085 +func (r *GetLendingHistoryRequest) After(after int64) *GetLendingHistoryRequest { + r.params["after"] = after + return r +} + +// Before sets pagination of data to return records newer than the requested ts, +// Unix timestamp format in milliseconds, e.g. 1597026383085 +func (r *GetLendingHistoryRequest) Before(before int64) *GetLendingHistoryRequest { + r.params["before"] = before + return r +} + +// Limit sets number of results per request. The maximum is 100. The default is 100. +func (r *GetLendingHistoryRequest) Limit(limit int64) *GetLendingHistoryRequest { + r.params["limit"] = limit + return r +} + +func (r *GetLendingHistoryRequest) Params() map[string]interface{} { + return r.params +} diff --git a/okx/pkg/models/funding_rest.go b/okx/pkg/models/funding_rest.go new file mode 100644 index 0000000..9119b34 --- /dev/null +++ b/okx/pkg/models/funding_rest.go @@ -0,0 +1,34 @@ +package models + +import "github.com/dasbd72/go-exchange-sdk/okx/pkg/cast" + +type ( + GetFundingBalancesRequest struct { + params map[string]interface{} + } + + GetFundingBalancesResponse struct { + BasicResponse + Balances []struct { + Ccy string `json:"ccy"` + Bal cast.JSONFloat64 `json:"bal"` + FrozenBal cast.JSONFloat64 `json:"frozenBal"` + AvailBal cast.JSONFloat64 `json:"availBal"` + } `json:"data,omitempty"` + } +) + +func NewGetFundingBalancesRequest() *GetFundingBalancesRequest { + return &GetFundingBalancesRequest{ + params: make(map[string]interface{}), + } +} + +func (r *GetFundingBalancesRequest) Ccy(ccy string) *GetFundingBalancesRequest { + r.params["ccy"] = ccy + return r +} + +func (r *GetFundingBalancesRequest) Params() map[string]interface{} { + return r.params +} diff --git a/okx/pkg/models/market_rest.go b/okx/pkg/models/market_rest.go new file mode 100644 index 0000000..ced3b06 --- /dev/null +++ b/okx/pkg/models/market_rest.go @@ -0,0 +1,76 @@ +package models + +import "github.com/dasbd72/go-exchange-sdk/okx/pkg/cast" + +type ( + Tickers struct { + InstID string `json:"instId"` + InstType string `json:"instType"` + Last cast.JSONFloat64 `json:"last"` + LastSz cast.JSONFloat64 `json:"lastSz"` + AskPx cast.JSONFloat64 `json:"askPx"` + AskSz cast.JSONFloat64 `json:"askSz"` + BidPx cast.JSONFloat64 `json:"bidPx"` + BidSz cast.JSONFloat64 `json:"bidSz"` + Open24h cast.JSONFloat64 `json:"open24h"` + High24h cast.JSONFloat64 `json:"high24h"` + Low24h cast.JSONFloat64 `json:"low24h"` + VolCcy24h cast.JSONFloat64 `json:"volCcy24h"` + Vol24h cast.JSONFloat64 `json:"vol24h"` + SodUtc0 cast.JSONFloat64 `json:"sodUtc0"` + SodUtc8 cast.JSONFloat64 `json:"sodUtc8"` + TS cast.JSONTime `json:"ts"` + } + + GetTickersRequest struct { + params map[string]interface{} + } + + GetTickersResponse struct { + BasicResponse + Tickers []Tickers `json:"data,omitempty"` + } + + GetTickerRequest struct { + params map[string]interface{} + } + + GetTickerResponse struct { + BasicResponse + Tickers []Tickers `json:"data,omitempty"` + } +) + +func NewGetTickersRequest(instType string) *GetTickersRequest { + return &GetTickersRequest{ + params: map[string]interface{}{ + "instType": instType, + }, + } +} + +func (r *GetTickersRequest) Uly(uly string) *GetTickersRequest { + r.params["uly"] = uly + return r +} + +func (r *GetTickersRequest) InstFamily(instFamily string) *GetTickersRequest { + r.params["instFamily"] = instFamily + return r +} + +func (r *GetTickersRequest) Params() map[string]interface{} { + return r.params +} + +func NewGetTickerRequest(instID string) *GetTickerRequest { + return &GetTickerRequest{ + params: map[string]interface{}{ + "instId": instID, + }, + } +} + +func (r *GetTickerRequest) Params() map[string]interface{} { + return r.params +} diff --git a/okx/pkg/models/trading_rest.go b/okx/pkg/models/trading_rest.go new file mode 100644 index 0000000..6869201 --- /dev/null +++ b/okx/pkg/models/trading_rest.go @@ -0,0 +1,72 @@ +package models + +import "github.com/dasbd72/go-exchange-sdk/okx/pkg/cast" + +type ( + GetBalanceRequest struct { + params map[string]interface{} + } + + GetBalanceResponse struct { + BasicResponse + Balances []*struct { + UTime cast.JSONTime `json:"uTime"` + TotalEq cast.JSONFloat64 `json:"totalEq"` + IsoEq cast.JSONFloat64 `json:"isoEq,omitempty"` + AdjEq cast.JSONFloat64 `json:"adjEq,omitempty"` + OrdFroz cast.JSONFloat64 `json:"ordFroz,omitempty"` + Imr cast.JSONFloat64 `json:"imr,omitempty"` + Mmr cast.JSONFloat64 `json:"mmr,omitempty"` + BorrowFroz cast.JSONFloat64 `json:"borrowFroz,omitempty"` + MgnRatio cast.JSONFloat64 `json:"mgnRatio,omitempty"` + NotionalUsd cast.JSONFloat64 `json:"notionalUsd,omitempty"` + Upl cast.JSONFloat64 `json:"upl,omitempty"` + Details []*struct { + Ccy string `json:"ccy"` + Eq cast.JSONFloat64 `json:"eq"` + CashBal cast.JSONFloat64 `json:"cashBal"` + UTime cast.JSONTime `json:"uTime"` + IsoEq cast.JSONFloat64 `json:"isoEq,omitempty"` + AvailEq cast.JSONFloat64 `json:"availEq,omitempty"` + DisEq cast.JSONFloat64 `json:"disEq"` + FixedBal cast.JSONFloat64 `json:"fixedBal,omitempty"` + AvailBal cast.JSONFloat64 `json:"availBal"` + FrozenBal cast.JSONFloat64 `json:"frozenBal"` + OrdFrozen cast.JSONFloat64 `json:"ordFrozen,omitempty"` + Liab cast.JSONFloat64 `json:"liab,omitempty"` + Upl cast.JSONFloat64 `json:"upl,omitempty"` + UplLiab cast.JSONFloat64 `json:"uplLiab,omitempty"` + CrossLiab cast.JSONFloat64 `json:"crossLiab,omitempty"` + IsoLiab cast.JSONFloat64 `json:"isoLiab,omitempty"` + MgnRatio cast.JSONFloat64 `json:"mgnRatio,omitempty"` + Interest cast.JSONFloat64 `json:"interest,omitempty"` + Twap cast.JSONFloat64 `json:"twap,omitempty"` + MaxLoan cast.JSONFloat64 `json:"maxLoan,omitempty"` + EqUsd cast.JSONFloat64 `json:"eqUsd"` + BorrowFroz cast.JSONFloat64 `json:"borrowFroz,omitempty"` + NotionalLever cast.JSONFloat64 `json:"notionalLever,omitempty"` + StgyEq cast.JSONFloat64 `json:"stgyEq"` + IsoUpl cast.JSONFloat64 `json:"isoUpl,omitempty"` + SpotInUseAmt cast.JSONFloat64 `json:"spotInUseAmt,omitempty"` + SpotIsoBal cast.JSONFloat64 `json:"spotIsoBal,omitempty"` + Imr cast.JSONFloat64 `json:"imr,omitempty"` + Mmr cast.JSONFloat64 `json:"mmr,omitempty"` + } `json:"details,omitempty"` + } `json:"data,omitempty"` + } +) + +func NewGetBalanceRequest() *GetBalanceRequest { + return &GetBalanceRequest{ + params: map[string]interface{}{}, + } +} + +func (r *GetBalanceRequest) Ccy(ccy string) *GetBalanceRequest { + r.params["ccy"] = ccy + return r +} + +func (r *GetBalanceRequest) Params() map[string]interface{} { + return r.params +} diff --git a/okx/client.go b/okx/pkg/rest/client.go similarity index 92% rename from okx/client.go rename to okx/pkg/rest/client.go index ca7a53f..b2f26ee 100644 --- a/okx/client.go +++ b/okx/pkg/rest/client.go @@ -1,4 +1,4 @@ -package okx +package rest import ( "context" @@ -10,6 +10,7 @@ import ( "io" "net/http" "net/url" + "time" ) const ( @@ -130,3 +131,12 @@ func sign(secret, message string) string { mac.Write([]byte(message)) return base64.StdEncoding.EncodeToString(mac.Sum(nil)) } + +func currentTimestamp() string { + return formatTimestamp(time.Now().UTC()) +} + +// formatTimestamp formats a time into string. +func formatTimestamp(t time.Time) string { + return t.Format("2006-01-02T15:04:05.999Z07:00") +} diff --git a/okx/time_test.go b/okx/pkg/rest/client_test.go similarity index 62% rename from okx/time_test.go rename to okx/pkg/rest/client_test.go index 0b01196..d842a77 100644 --- a/okx/time_test.go +++ b/okx/pkg/rest/client_test.go @@ -1,4 +1,4 @@ -package okx +package rest import ( "testing" @@ -7,6 +7,34 @@ import ( "github.com/google/go-cmp/cmp" ) +func Test_sign(t *testing.T) { + type args struct { + secret string + message string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "testcase 1", + args: args{ + secret: "secret", + message: "message", + }, + want: "i19IcCmVwVmMVz2x4hhmqbgl1KeU0WnXBgoDYFeWNgs=", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := sign(tt.args.secret, tt.args.message); got != tt.want { + t.Errorf("sign() = %v, want %v", got, tt.want) + } + }) + } +} + func TestFormatTimestamp(t *testing.T) { tpe, err := time.LoadLocation("Asia/Taipei") if err != nil { diff --git a/okx/errors.go b/okx/pkg/rest/errors.go similarity index 97% rename from okx/errors.go rename to okx/pkg/rest/errors.go index 71d81cb..cb8e31a 100644 --- a/okx/errors.go +++ b/okx/pkg/rest/errors.go @@ -1,4 +1,4 @@ -package okx +package rest import ( "fmt" diff --git a/okx/errors_test.go b/okx/pkg/rest/errors_test.go similarity index 98% rename from okx/errors_test.go rename to okx/pkg/rest/errors_test.go index 8a57a1d..acca8ce 100644 --- a/okx/errors_test.go +++ b/okx/pkg/rest/errors_test.go @@ -1,4 +1,4 @@ -package okx +package rest import ( "fmt" diff --git a/okx/pkg/rest/financial_service.go b/okx/pkg/rest/financial_service.go new file mode 100644 index 0000000..ce8556e --- /dev/null +++ b/okx/pkg/rest/financial_service.go @@ -0,0 +1,103 @@ +package rest + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/dasbd72/go-exchange-sdk/okx/pkg/models" +) + +// GetEarnOffers get the available earn offers +func (c *Client) GetEarnOffers(ctx context.Context, req *models.GetEarnOffersRequest, opts ...RequestOption) (*models.GetEarnOffersResponse, error) { + res, err := c.CallAPI(ctx, Request_builder{ + Method: http.MethodGet, + Endpoint: "/api/v5/finance/staking-defi/offers", + SecType: SecTypePrivate, + Params: req.Params(), + }.Build(), opts...) + if err != nil { + return nil, err + } + data := &models.GetEarnOffersResponse{} + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, nil +} + +// GetActiveEarnOrders get the active earn orders +func (c *Client) GetActiveEarnOrders(ctx context.Context, req *models.GetActiveEarnOrdersRequest, opts ...RequestOption) (*models.GetActiveEarnOrdersResponse, error) { + res, err := c.CallAPI(ctx, Request_builder{ + Method: http.MethodGet, + Endpoint: "/api/v5/finance/staking-defi/orders-active", + SecType: SecTypePrivate, + Params: req.Params(), + }.Build(), opts...) + if err != nil { + return nil, err + } + data := &models.GetActiveEarnOrdersResponse{} + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, nil +} + +// GetETHStakingBalance get balances in the ETH staking account +func (c *Client) GetETHStakingBalance(ctx context.Context, opts ...RequestOption) (*models.GetETHStakingBalanceResponse, error) { + res, err := c.CallAPI(ctx, Request_builder{ + Method: http.MethodGet, + Endpoint: "/api/v5/finance/staking-defi/eth/balance", + SecType: SecTypePrivate, + }.Build(), opts...) + if err != nil { + return nil, err + } + data := &models.GetETHStakingBalanceResponse{} + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, nil +} + +// GetSavingBalance get balances in the saving account +func (c *Client) GetSavingBalance(ctx context.Context, req *models.GetSavingBalanceRequest, opts ...RequestOption) (*models.GetSavingBalanceResponse, error) { + res, err := c.CallAPI(ctx, Request_builder{ + Method: http.MethodGet, + Endpoint: "/api/v5/finance/savings/balance", + SecType: SecTypePrivate, + Params: req.Params(), + }.Build(), opts...) + if err != nil { + return nil, err + } + data := &models.GetSavingBalanceResponse{} + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, nil +} + +// GetLendingHistory get the lending history +func (c *Client) GetLendingHistory(ctx context.Context, req *models.GetLendingHistoryRequest, opts ...RequestOption) (*models.GetLendingHistoryResponse, error) { + res, err := c.CallAPI(ctx, Request_builder{ + Method: http.MethodGet, + Endpoint: "/api/v5/finance/savings/lending-history", + SecType: SecTypePrivate, + Params: req.Params(), + }.Build(), opts...) + if err != nil { + return nil, err + } + data := &models.GetLendingHistoryResponse{} + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, nil +} diff --git a/okx/pkg/rest/funding_service.go b/okx/pkg/rest/funding_service.go new file mode 100644 index 0000000..d0d51e9 --- /dev/null +++ b/okx/pkg/rest/funding_service.go @@ -0,0 +1,28 @@ +package rest + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/dasbd72/go-exchange-sdk/okx/pkg/models" +) + +// GetFundingBalances get balances in the funding account +func (c *Client) GetFundingBalances(ctx context.Context, req *models.GetFundingBalancesRequest, opts ...RequestOption) (*models.GetFundingBalancesResponse, error) { + res, err := c.CallAPI(ctx, Request_builder{ + Method: http.MethodGet, + Endpoint: "/api/v5/asset/balances", + SecType: SecTypePrivate, + Params: req.Params(), + }.Build(), opts...) + if err != nil { + return nil, err + } + data := &models.GetFundingBalancesResponse{} + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, nil +} diff --git a/okx/pkg/rest/market_service.go b/okx/pkg/rest/market_service.go new file mode 100644 index 0000000..48d6f1e --- /dev/null +++ b/okx/pkg/rest/market_service.go @@ -0,0 +1,47 @@ +package rest + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/dasbd72/go-exchange-sdk/okx/pkg/models" +) + +// GetTickers get tickers of instruments +func (c *Client) GetTickers(ctx context.Context, req *models.GetTickersRequest, opts ...RequestOption) (*models.GetTickersResponse, error) { + res, err := c.CallAPI(ctx, Request_builder{ + Method: http.MethodGet, + Endpoint: "/api/v5/market/tickers", + SecType: SecTypePublic, + Params: req.Params(), + }.Build(), opts...) + if err != nil { + return nil, err + } + data := &models.GetTickersResponse{} + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, nil +} + +// GetTicker get ticker of instrument +func (c *Client) GetTicker(ctx context.Context, req *models.GetTickerRequest, opts ...RequestOption) (*models.GetTickerResponse, error) { + res, err := c.CallAPI(ctx, Request_builder{ + Method: http.MethodGet, + Endpoint: "/api/v5/market/ticker", + SecType: SecTypePublic, + Params: req.Params(), + }.Build(), opts...) + if err != nil { + return nil, err + } + data := &models.GetTickerResponse{} + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, nil +} diff --git a/okx/request.go b/okx/pkg/rest/request.go similarity index 99% rename from okx/request.go rename to okx/pkg/rest/request.go index 3da686a..e90b786 100644 --- a/okx/request.go +++ b/okx/pkg/rest/request.go @@ -1,4 +1,4 @@ -package okx +package rest import "net/http" diff --git a/okx/request_test.go b/okx/pkg/rest/request_test.go similarity index 98% rename from okx/request_test.go rename to okx/pkg/rest/request_test.go index 5a0ff38..69eed5d 100644 --- a/okx/request_test.go +++ b/okx/pkg/rest/request_test.go @@ -1,4 +1,4 @@ -package okx +package rest import ( "net/http" diff --git a/okx/pkg/rest/trading_service.go b/okx/pkg/rest/trading_service.go new file mode 100644 index 0000000..6719757 --- /dev/null +++ b/okx/pkg/rest/trading_service.go @@ -0,0 +1,28 @@ +package rest + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/dasbd72/go-exchange-sdk/okx/pkg/models" +) + +// GetBalance get account balance +func (c *Client) GetBalance(ctx context.Context, req *models.GetBalanceRequest, opts ...RequestOption) (*models.GetBalanceResponse, error) { + res, err := c.CallAPI(ctx, Request_builder{ + Method: http.MethodGet, + Endpoint: "/api/v5/account/balance", + SecType: SecTypePrivate, + Params: req.Params(), + }.Build(), opts...) + if err != nil { + return nil, err + } + data := &models.GetBalanceResponse{} + err = json.Unmarshal(res, data) + if err != nil { + return nil, err + } + return data, nil +} diff --git a/okx/time.go b/okx/time.go deleted file mode 100644 index 38cea00..0000000 --- a/okx/time.go +++ /dev/null @@ -1,12 +0,0 @@ -package okx - -import "time" - -func currentTimestamp() string { - return formatTimestamp(time.Now().UTC()) -} - -// formatTimestamp formats a time into string. -func formatTimestamp(t time.Time) string { - return t.Format("2006-01-02T15:04:05.999Z07:00") -} diff --git a/okx/trading_rest_service.go b/okx/trading_rest_service.go deleted file mode 100644 index 5bc6874..0000000 --- a/okx/trading_rest_service.go +++ /dev/null @@ -1,91 +0,0 @@ -package okx - -import ( - "context" - "encoding/json" - "net/http" -) - -type ( - GetBalanceRequest struct { - params map[string]interface{} - } - - GetBalanceResponse struct { - BasicResponse - Balances []*struct { - UTime JSONTime `json:"uTime"` - TotalEq JSONFloat64 `json:"totalEq"` - IsoEq JSONFloat64 `json:"isoEq,omitempty"` - AdjEq JSONFloat64 `json:"adjEq,omitempty"` - OrdFroz JSONFloat64 `json:"ordFroz,omitempty"` - Imr JSONFloat64 `json:"imr,omitempty"` - Mmr JSONFloat64 `json:"mmr,omitempty"` - BorrowFroz JSONFloat64 `json:"borrowFroz,omitempty"` - MgnRatio JSONFloat64 `json:"mgnRatio,omitempty"` - NotionalUsd JSONFloat64 `json:"notionalUsd,omitempty"` - Upl JSONFloat64 `json:"upl,omitempty"` - Details []*struct { - Ccy string `json:"ccy"` - Eq JSONFloat64 `json:"eq"` - CashBal JSONFloat64 `json:"cashBal"` - UTime JSONTime `json:"uTime"` - IsoEq JSONFloat64 `json:"isoEq,omitempty"` - AvailEq JSONFloat64 `json:"availEq,omitempty"` - DisEq JSONFloat64 `json:"disEq"` - FixedBal JSONFloat64 `json:"fixedBal,omitempty"` - AvailBal JSONFloat64 `json:"availBal"` - FrozenBal JSONFloat64 `json:"frozenBal"` - OrdFrozen JSONFloat64 `json:"ordFrozen,omitempty"` - Liab JSONFloat64 `json:"liab,omitempty"` - Upl JSONFloat64 `json:"upl,omitempty"` - UplLiab JSONFloat64 `json:"uplLiab,omitempty"` - CrossLiab JSONFloat64 `json:"crossLiab,omitempty"` - IsoLiab JSONFloat64 `json:"isoLiab,omitempty"` - MgnRatio JSONFloat64 `json:"mgnRatio,omitempty"` - Interest JSONFloat64 `json:"interest,omitempty"` - Twap JSONFloat64 `json:"twap,omitempty"` - MaxLoan JSONFloat64 `json:"maxLoan,omitempty"` - EqUsd JSONFloat64 `json:"eqUsd"` - BorrowFroz JSONFloat64 `json:"borrowFroz,omitempty"` - NotionalLever JSONFloat64 `json:"notionalLever,omitempty"` - StgyEq JSONFloat64 `json:"stgyEq"` - IsoUpl JSONFloat64 `json:"isoUpl,omitempty"` - SpotInUseAmt JSONFloat64 `json:"spotInUseAmt,omitempty"` - SpotIsoBal JSONFloat64 `json:"spotIsoBal,omitempty"` - Imr JSONFloat64 `json:"imr,omitempty"` - Mmr JSONFloat64 `json:"mmr,omitempty"` - } `json:"details,omitempty"` - } `json:"data,omitempty"` - } -) - -func NewGetBalanceRequest() *GetBalanceRequest { - return &GetBalanceRequest{ - params: map[string]interface{}{}, - } -} - -func (r *GetBalanceRequest) Ccy(ccy string) *GetBalanceRequest { - r.params["ccy"] = ccy - return r -} - -// GetBalance get account balance -func (c *Client) GetBalance(ctx context.Context, req *GetBalanceRequest, opts ...RequestOption) (*GetBalanceResponse, error) { - res, err := c.CallAPI(ctx, Request_builder{ - Method: http.MethodGet, - Endpoint: "/api/v5/account/balance", - SecType: SecTypePrivate, - Params: req.params, - }.Build(), opts...) - if err != nil { - return nil, err - } - data := &GetBalanceResponse{} - err = json.Unmarshal(res, data) - if err != nil { - return nil, err - } - return data, nil -}