mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-01 15:10:44 +00:00
exchanges: Refactor time handling and other minor improvements (#1948)
* exchanges: Refactor time handling and other minor improvements - Updated Kraken wrapper to utilise new time handling methods. - Simplified Kucoin types by removing unnecessary structures and using direct JSON unmarshalling. - Improved websocket handling in Kucoin to directly parse candlestick data. - Modified Lbank types to use the new time representation. - Adjusted Poloniex wrapper and types to utilise the new time handling. - Updated Yobit types and wrapper to reflect changes in time representation. - Introduced DateTime type for better handling of specific time formats. - Added tests for DateTime unmarshalling to ensure correctness. - Rid UTC().Unix and UTC().UnixMilli as it's not needed - Correct Huobi timestamp usage for some endpoints. - Rid RFC3339 time parsing since Go does that automatically. * exchanges: Refactor JSON unmarshalling for various types and improve test coverage * linter: Update error message in TestGetKlines * refactor: Simplify JSON unmarshalling in MovementHistory and improve test assertions in GetKlines * refactor: Improve JSON unmarshalling for channel name and clarify comment in wsProcessOpenOrders * refactor: Update time handling in Huobi types to use types.Time for createdAt fields and relax GetLiquidationOrders test * refactor: Move wsTicker, wsSpread, wsTrades, and wsCandle types to kraken_types.go for better organistion * refactor: Add validation for underlying parameter in GetExpirationTime and update tests
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -752,14 +753,13 @@ func (g *Gateio) GetMySpotTradingHistory(ctx context.Context, p currency.Pair, o
|
||||
|
||||
// GetServerTime retrieves current server time
|
||||
func (g *Gateio) GetServerTime(ctx context.Context, _ asset.Item) (time.Time, error) {
|
||||
resp := struct {
|
||||
ServerTime int64 `json:"server_time"`
|
||||
}{}
|
||||
err := g.SendHTTPRequest(ctx, exchange.RestSpot, publicGetServerTimeEPL, gateioSpotServerTime, &resp)
|
||||
if err != nil {
|
||||
var resp struct {
|
||||
ServerTime types.Time `json:"server_time"`
|
||||
}
|
||||
if err := g.SendHTTPRequest(ctx, exchange.RestSpot, publicGetServerTimeEPL, gateioSpotServerTime, &resp); err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
return time.Unix(resp.ServerTime, 0), nil
|
||||
return resp.ServerTime.Time(), nil
|
||||
}
|
||||
|
||||
// CountdownCancelorders Countdown cancel orders
|
||||
@@ -876,6 +876,11 @@ func (g *Gateio) CancelPriceTriggeredOrder(ctx context.Context, orderID string)
|
||||
|
||||
// GenerateSignature returns hash for authenticated requests
|
||||
func (g *Gateio) GenerateSignature(secret, method, path, query string, body any, dtime time.Time) (string, error) {
|
||||
rawQuery, err := url.QueryUnescape(query)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
h := sha512.New()
|
||||
if body != nil {
|
||||
val, err := json.Marshal(body)
|
||||
@@ -886,12 +891,8 @@ func (g *Gateio) GenerateSignature(secret, method, path, query string, body any,
|
||||
}
|
||||
h.Write(nil)
|
||||
hashedPayload := hex.EncodeToString(h.Sum(nil))
|
||||
t := strconv.FormatInt(dtime.Unix(), 10)
|
||||
rawQuery, err := url.QueryUnescape(query)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
msg := method + "\n" + path + "\n" + rawQuery + "\n" + hashedPayload + "\n" + t
|
||||
|
||||
msg := method + "\n" + path + "\n" + rawQuery + "\n" + hashedPayload + "\n" + strconv.FormatInt(dtime.Unix(), 10)
|
||||
mac := hmac.New(sha512.New, []byte(secret))
|
||||
mac.Write([]byte(msg))
|
||||
return hex.EncodeToString(mac.Sum(nil)), nil
|
||||
@@ -3116,15 +3117,18 @@ func (g *Gateio) GetAllOptionsUnderlyings(ctx context.Context) ([]OptionUnderlyi
|
||||
|
||||
// GetExpirationTime return the expiration time for the provided underlying.
|
||||
func (g *Gateio) GetExpirationTime(ctx context.Context, underlying string) (time.Time, error) {
|
||||
var timestamp []float64
|
||||
err := g.SendHTTPRequest(ctx, exchange.RestSpot, publicExpirationOptionsEPL, gateioOptionExpiration+"?underlying="+underlying, ×tamp)
|
||||
if underlying == "" {
|
||||
return time.Time{}, errInvalidUnderlying
|
||||
}
|
||||
var timestamps []types.Time
|
||||
err := g.SendHTTPRequest(ctx, exchange.RestSpot, publicExpirationOptionsEPL, gateioOptionExpiration+"?underlying="+underlying, ×tamps)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
if len(timestamp) == 0 {
|
||||
if len(timestamps) == 0 {
|
||||
return time.Time{}, errNoValidResponseFromServer
|
||||
}
|
||||
return time.Unix(int64(timestamp[0]), 0), nil
|
||||
return timestamps[0].Time(), nil
|
||||
}
|
||||
|
||||
// GetAllContractOfUnderlyingWithinExpiryDate retrieves list of contracts of the specified underlying and expiry time.
|
||||
|
||||
@@ -1473,9 +1473,10 @@ func TestGetAllOptionsUnderlyings(t *testing.T) {
|
||||
|
||||
func TestGetExpirationTime(t *testing.T) {
|
||||
t.Parallel()
|
||||
if _, err := g.GetExpirationTime(t.Context(), "BTC_USDT"); err != nil {
|
||||
t.Errorf("%s GetExpirationTime() error %v", g.Name, err)
|
||||
}
|
||||
_, err := g.GetExpirationTime(t.Context(), "")
|
||||
assert.ErrorIs(t, err, errInvalidUnderlying)
|
||||
_, err = g.GetExpirationTime(t.Context(), "BTC_USDT")
|
||||
assert.NoError(t, err, "GetExpirationTime should not error")
|
||||
}
|
||||
|
||||
func TestGetAllContractOfUnderlyingWithinExpiryDate(t *testing.T) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/trade"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -433,7 +434,7 @@ func (g *Gateio) processOrderbookSnapshot(incoming []byte, lastPushed time.Time)
|
||||
|
||||
func (g *Gateio) processSpotOrders(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsSpotOrder `json:"result"`
|
||||
@@ -481,7 +482,7 @@ func (g *Gateio) processUserPersonalTrades(data []byte) error {
|
||||
}
|
||||
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsUserPersonalTrade `json:"result"`
|
||||
@@ -512,7 +513,7 @@ func (g *Gateio) processUserPersonalTrades(data []byte) error {
|
||||
|
||||
func (g *Gateio) processSpotBalances(ctx context.Context, data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsSpotBalance `json:"result"`
|
||||
@@ -545,7 +546,7 @@ func (g *Gateio) processSpotBalances(ctx context.Context, data []byte) error {
|
||||
|
||||
func (g *Gateio) processMarginBalances(ctx context.Context, data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsMarginBalance `json:"result"`
|
||||
@@ -577,7 +578,7 @@ func (g *Gateio) processMarginBalances(ctx context.Context, data []byte) error {
|
||||
|
||||
func (g *Gateio) processFundingBalances(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFundingBalance `json:"result"`
|
||||
@@ -592,7 +593,7 @@ func (g *Gateio) processFundingBalances(data []byte) error {
|
||||
|
||||
func (g *Gateio) processCrossMarginBalance(ctx context.Context, data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsCrossMarginBalance `json:"result"`
|
||||
@@ -624,7 +625,7 @@ func (g *Gateio) processCrossMarginBalance(ctx context.Context, data []byte) err
|
||||
|
||||
func (g *Gateio) processCrossMarginLoans(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result WsCrossMarginLoan `json:"result"`
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/trade"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -299,7 +300,7 @@ func (g *Gateio) generateFuturesPayload(ctx context.Context, conn websocket.Conn
|
||||
|
||||
func (g *Gateio) processFuturesTickers(data []byte, assetType asset.Item) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFutureTicker `json:"result"`
|
||||
@@ -319,7 +320,7 @@ func (g *Gateio) processFuturesTickers(data []byte, assetType asset.Item) error
|
||||
Last: resp.Result[x].Last.Float64(),
|
||||
AssetType: assetType,
|
||||
Pair: resp.Result[x].Contract,
|
||||
LastUpdated: time.Unix(resp.Time, 0),
|
||||
LastUpdated: resp.Time.Time(),
|
||||
}
|
||||
}
|
||||
g.Websocket.DataHandler <- tickerPriceDatas
|
||||
@@ -333,7 +334,7 @@ func (g *Gateio) processFuturesTrades(data []byte, assetType asset.Item) error {
|
||||
}
|
||||
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFuturesTrades `json:"result"`
|
||||
@@ -360,7 +361,7 @@ func (g *Gateio) processFuturesTrades(data []byte, assetType asset.Item) error {
|
||||
|
||||
func (g *Gateio) processFuturesCandlesticks(data []byte, assetType asset.Item) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []FuturesCandlestick `json:"result"`
|
||||
@@ -514,7 +515,7 @@ func (g *Gateio) processFuturesOrderbookSnapshot(event string, incoming []byte,
|
||||
|
||||
func (g *Gateio) processFuturesOrdersPushData(data []byte, assetType asset.Item) ([]order.Detail, error) {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFuturesOrder `json:"result"`
|
||||
@@ -567,7 +568,7 @@ func (g *Gateio) procesFuturesUserTrades(data []byte, assetType asset.Item) erro
|
||||
}
|
||||
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFuturesUserTrade `json:"result"`
|
||||
@@ -594,7 +595,7 @@ func (g *Gateio) procesFuturesUserTrades(data []byte, assetType asset.Item) erro
|
||||
|
||||
func (g *Gateio) processFuturesLiquidatesNotification(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFuturesLiquidationNotification `json:"result"`
|
||||
@@ -609,7 +610,7 @@ func (g *Gateio) processFuturesLiquidatesNotification(data []byte) error {
|
||||
|
||||
func (g *Gateio) processFuturesAutoDeleveragesNotification(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFuturesAutoDeleveragesNotification `json:"result"`
|
||||
@@ -624,7 +625,7 @@ func (g *Gateio) processFuturesAutoDeleveragesNotification(data []byte) error {
|
||||
|
||||
func (g *Gateio) processPositionCloseData(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsPositionClose `json:"result"`
|
||||
@@ -639,7 +640,7 @@ func (g *Gateio) processPositionCloseData(data []byte) error {
|
||||
|
||||
func (g *Gateio) processBalancePushData(ctx context.Context, data []byte, assetType asset.Item) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsBalance `json:"result"`
|
||||
@@ -675,7 +676,7 @@ func (g *Gateio) processBalancePushData(ctx context.Context, data []byte, assetT
|
||||
|
||||
func (g *Gateio) processFuturesReduceRiskLimitNotification(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFuturesReduceRiskLimitNotification `json:"result"`
|
||||
@@ -690,7 +691,7 @@ func (g *Gateio) processFuturesReduceRiskLimitNotification(data []byte) error {
|
||||
|
||||
func (g *Gateio) processFuturesPositionsNotification(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFuturesPosition `json:"result"`
|
||||
@@ -705,7 +706,7 @@ func (g *Gateio) processFuturesPositionsNotification(data []byte) error {
|
||||
|
||||
func (g *Gateio) processFuturesAutoOrderPushData(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsFuturesAutoOrder `json:"result"`
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/trade"
|
||||
"github.com/thrasher-corp/gocryptotrader/log"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -387,7 +388,7 @@ func (g *Gateio) processOptionsTradesPushData(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsOptionsTrades `json:"result"`
|
||||
@@ -453,7 +454,7 @@ func (g *Gateio) processOptionsContractPushData(incoming []byte) error {
|
||||
|
||||
func (g *Gateio) processOptionsCandlestickPushData(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsOptionsContractCandlestick `json:"result"`
|
||||
@@ -604,7 +605,7 @@ func (g *Gateio) processOptionsOrderbookSnapshotPushData(event string, incoming
|
||||
|
||||
func (g *Gateio) processOptionsOrderPushData(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsOptionsOrder `json:"result"`
|
||||
@@ -646,7 +647,7 @@ func (g *Gateio) processOptionsUserTradesPushData(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsOptionsUserTrade `json:"result"`
|
||||
@@ -672,7 +673,7 @@ func (g *Gateio) processOptionsUserTradesPushData(data []byte) error {
|
||||
|
||||
func (g *Gateio) processOptionsLiquidatesPushData(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsOptionsLiquidates `json:"result"`
|
||||
@@ -687,7 +688,7 @@ func (g *Gateio) processOptionsLiquidatesPushData(data []byte) error {
|
||||
|
||||
func (g *Gateio) processOptionsUsersPersonalSettlementsPushData(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsOptionsUserSettlement `json:"result"`
|
||||
@@ -702,7 +703,7 @@ func (g *Gateio) processOptionsUsersPersonalSettlementsPushData(data []byte) err
|
||||
|
||||
func (g *Gateio) processOptionsPositionPushData(data []byte) error {
|
||||
resp := struct {
|
||||
Time int64 `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
Channel string `json:"channel"`
|
||||
Event string `json:"event"`
|
||||
Result []WsOptionsPosition `json:"result"`
|
||||
|
||||
Reference in New Issue
Block a user