mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
types/time, exchanges/kraken: Refactor spot/futures time types (#1936)
* types/time, exchanges/kraken: Refactor spot/futures time types
- Updated WSFuturesTickerData, WsFuturesTradeData, and other related structs to replace int64 timestamps with the new types.Time.
- Adjusted related test cases to accommodate changes in timestamp handling.
- Modified functions in kraken_wrapper and kraken_websocket to utilise the new Time type for better time management.
- Enhanced JSON unmarshalling in the Time type to handle various timestamp formats, including "0" and "0.0".
* refactor: Update JSON field name/types and improve perf
* types/time: revert to more precise check, just check for 'n'
* refactor: Ryan the F1 driver is so back 🏎️
* refactor: Enhance UnmarshalJSON error handling and simplify test cases
* ocd: Fix trigger
This commit is contained in:
@@ -2,8 +2,10 @@ package kraken
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -27,31 +29,31 @@ var (
|
||||
|
||||
// WSFuturesTickerData stores ws ticker data for futures websocket
|
||||
type WSFuturesTickerData struct {
|
||||
Time int64 `json:"time"`
|
||||
Feed string `json:"feed"`
|
||||
ProductID string `json:"product_id"`
|
||||
Bid float64 `json:"bid"`
|
||||
Ask float64 `json:"ask"`
|
||||
BidSize float64 `json:"bid_size"`
|
||||
AskSize float64 `json:"ask_size"`
|
||||
Volume float64 `json:"volume"`
|
||||
DTM float64 `json:"dtm"`
|
||||
Leverage string `json:"leverage"`
|
||||
Index float64 `json:"index"`
|
||||
Premium float64 `json:"premium"`
|
||||
Last float64 `json:"last"`
|
||||
Change float64 `json:"change"`
|
||||
Suspended bool `json:"suspended"`
|
||||
Tag string `json:"tag"`
|
||||
Pair string `json:"pair"`
|
||||
OpenInterest float64 `json:"openinterest"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
MaturityTime int64 `json:"maturityTime"`
|
||||
FundingRate float64 `json:"funding_rate"`
|
||||
FundingRatePrediction float64 `json:"funding_rate_prediction"`
|
||||
RelativeFundingRate float64 `json:"relative_funding_rate"`
|
||||
RelativeFundingRatePrediction float64 `json:"relative_funding_rate_prediction"`
|
||||
NextFundingRateTime int64 `json:"next_funding_rate_time"`
|
||||
Time types.Time `json:"time"`
|
||||
Feed string `json:"feed"`
|
||||
ProductID string `json:"product_id"`
|
||||
Bid float64 `json:"bid"`
|
||||
Ask float64 `json:"ask"`
|
||||
BidSize float64 `json:"bid_size"`
|
||||
AskSize float64 `json:"ask_size"`
|
||||
Volume float64 `json:"volume"`
|
||||
DTM float64 `json:"dtm"`
|
||||
Leverage string `json:"leverage"`
|
||||
Index float64 `json:"index"`
|
||||
Premium float64 `json:"premium"`
|
||||
Last float64 `json:"last"`
|
||||
Change float64 `json:"change"`
|
||||
Suspended bool `json:"suspended"`
|
||||
Tag string `json:"tag"`
|
||||
Pair string `json:"pair"`
|
||||
OpenInterest float64 `json:"openinterest"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
MaturityTime types.Time `json:"maturityTime"`
|
||||
FundingRate float64 `json:"funding_rate"`
|
||||
FundingRatePrediction float64 `json:"funding_rate_prediction"`
|
||||
RelativeFundingRate float64 `json:"relative_funding_rate"`
|
||||
RelativeFundingRatePrediction float64 `json:"relative_funding_rate_prediction"`
|
||||
NextFundingRateTime types.Time `json:"next_funding_rate_time"`
|
||||
}
|
||||
|
||||
// WsFuturesTradeData stores public trade data for futures websocket
|
||||
@@ -59,14 +61,14 @@ type WsFuturesTradeData struct {
|
||||
Feed string `json:"feed"`
|
||||
ProductID string `json:"product_id"`
|
||||
Trades []struct {
|
||||
Feed string `json:"feed"`
|
||||
ProductID string `json:"product_id"`
|
||||
Side string `json:"side"`
|
||||
ProductType string `json:"type"`
|
||||
Seq int64 `json:"seq"`
|
||||
Time int64 `json:"time"`
|
||||
Quantity float64 `json:"qty"`
|
||||
Price float64 `json:"price"`
|
||||
Feed string `json:"feed"`
|
||||
ProductID string `json:"product_id"`
|
||||
Side string `json:"side"`
|
||||
ProductType string `json:"type"`
|
||||
Seq int64 `json:"seq"`
|
||||
Time types.Time `json:"time"`
|
||||
Quantity float64 `json:"qty"`
|
||||
Price float64 `json:"price"`
|
||||
} `json:"trades"`
|
||||
}
|
||||
|
||||
@@ -103,17 +105,17 @@ type WsVerboseOpenOrders struct {
|
||||
Feed string `json:"feed"`
|
||||
Account string `json:"account"`
|
||||
Orders []struct {
|
||||
Instrument string `json:"instrument"`
|
||||
Time int64 `json:"time"`
|
||||
LastUpdateTime int64 `json:"last_update_time"`
|
||||
Qty float64 `json:"qty"`
|
||||
Filled float64 `json:"filled"`
|
||||
LimitPrice float64 `json:"limit_price"`
|
||||
StopPrice float64 `json:"stop_price"`
|
||||
OrderType string `json:"type"`
|
||||
OrderID string `json:"order_id"`
|
||||
Direction int64 `json:"direction"`
|
||||
ReduceOnly bool `json:"reduce_only"`
|
||||
Instrument string `json:"instrument"`
|
||||
Time types.Time `json:"time"`
|
||||
LastUpdateTime types.Time `json:"last_update_time"`
|
||||
Qty float64 `json:"qty"`
|
||||
Filled float64 `json:"filled"`
|
||||
LimitPrice float64 `json:"limit_price"`
|
||||
StopPrice float64 `json:"stop_price"`
|
||||
OrderType string `json:"type"`
|
||||
OrderID string `json:"order_id"`
|
||||
Direction int64 `json:"direction"`
|
||||
ReduceOnly bool `json:"reduce_only"`
|
||||
} `json:"orders"`
|
||||
}
|
||||
|
||||
@@ -161,16 +163,16 @@ type WsFuturesFillsData struct {
|
||||
Feed string `json:"feed"`
|
||||
Account string `json:"account"`
|
||||
Fills []struct {
|
||||
Instrument string `json:"instrument"`
|
||||
Time int64 `json:"time"`
|
||||
Price float64 `json:"price"`
|
||||
Seq int64 `json:"seq"`
|
||||
Buy bool `json:"buy"`
|
||||
Quantity float64 `json:"qty"`
|
||||
OrderID string `json:"order_id"`
|
||||
ClientOrderID string `json:"cli_order_id"`
|
||||
FillID string `json:"fill_id"`
|
||||
FillType string `json:"fill_type"`
|
||||
Instrument string `json:"instrument"`
|
||||
Time types.Time `json:"time"`
|
||||
Price float64 `json:"price"`
|
||||
Seq int64 `json:"seq"`
|
||||
Buy bool `json:"buy"`
|
||||
Quantity float64 `json:"qty"`
|
||||
OrderID string `json:"order_id"`
|
||||
ClientOrderID string `json:"cli_order_id"`
|
||||
FillID string `json:"fill_id"`
|
||||
FillType string `json:"fill_type"`
|
||||
} `json:"fills"`
|
||||
}
|
||||
|
||||
@@ -179,17 +181,17 @@ type WsFuturesOpenOrders struct {
|
||||
Feed string `json:"feed"`
|
||||
Account string `json:"account"`
|
||||
Orders []struct {
|
||||
Instrument string `json:"instrument"`
|
||||
Time int64 `json:"time"`
|
||||
LastUpdateTime int64 `json:"last_update_time"`
|
||||
Qty float64 `json:"qty"`
|
||||
Filled float64 `json:"filled"`
|
||||
LimitPrice float64 `json:"limit_price"`
|
||||
StopPrice float64 `json:"stop_price"`
|
||||
OrderType string `json:"order_type"`
|
||||
OrderID string `json:"order_id"`
|
||||
Direction string `json:"direction"`
|
||||
ReduceOnly bool `json:"reduce_only"`
|
||||
Instrument string `json:"instrument"`
|
||||
Time types.Time `json:"time"`
|
||||
LastUpdateTime types.Time `json:"last_update_time"`
|
||||
Qty float64 `json:"qty"`
|
||||
Filled float64 `json:"filled"`
|
||||
LimitPrice float64 `json:"limit_price"`
|
||||
StopPrice float64 `json:"stop_price"`
|
||||
OrderType string `json:"order_type"`
|
||||
OrderID string `json:"order_id"`
|
||||
Direction string `json:"direction"`
|
||||
ReduceOnly bool `json:"reduce_only"`
|
||||
} `json:"orders"`
|
||||
}
|
||||
|
||||
@@ -214,11 +216,11 @@ type WsAccountBalancesAndMargin struct {
|
||||
type WsFuturesNotifications struct {
|
||||
Feed string `json:"feed"`
|
||||
Notifications []struct {
|
||||
ID int64 `json:"id"`
|
||||
NotificationType string `json:"notificationType"`
|
||||
Priority string `json:"priority"`
|
||||
Note string `json:"note"`
|
||||
EffectiveTime int64 `json:"effective_time"`
|
||||
ID int64 `json:"id"`
|
||||
NotificationType string `json:"notificationType"`
|
||||
Priority string `json:"priority"`
|
||||
Note string `json:"note"`
|
||||
EffectiveTime types.Time `json:"effective_time"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +231,7 @@ type assetTranslatorStore struct {
|
||||
|
||||
// FuturesOrderbookData stores orderbook data for futures
|
||||
type FuturesOrderbookData struct {
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
Orderbook struct {
|
||||
Bids [][2]float64 `json:"bids"`
|
||||
Asks [][2]float64 `json:"asks"`
|
||||
@@ -238,21 +240,21 @@ type FuturesOrderbookData struct {
|
||||
|
||||
// TimeResponse type
|
||||
type TimeResponse struct {
|
||||
Unixtime int64 `json:"unixtime"`
|
||||
Rfc1123 string `json:"rfc1123"`
|
||||
Unixtime types.Time `json:"unixtime"`
|
||||
Rfc1123 string `json:"rfc1123"`
|
||||
}
|
||||
|
||||
// FuturesInstrumentData stores info for futures market
|
||||
type FuturesInstrumentData struct {
|
||||
Instruments []struct {
|
||||
Symbol string `json:"symbol"`
|
||||
FutureType string `json:"type"`
|
||||
Underlying string `json:"underlying"`
|
||||
OpeningDate string `json:"openingDate"`
|
||||
LastTradingTime string `json:"lastTradingTime"`
|
||||
TickSize float64 `json:"tickSize"`
|
||||
ContractSize float64 `json:"contractSize"`
|
||||
Tradable bool `json:"tradeable"`
|
||||
Symbol string `json:"symbol"`
|
||||
FutureType string `json:"type"`
|
||||
Underlying string `json:"underlying"`
|
||||
OpeningDate time.Time `json:"openingDate"`
|
||||
LastTradingTime time.Time `json:"lastTradingTime"`
|
||||
TickSize float64 `json:"tickSize"`
|
||||
ContractSize float64 `json:"contractSize"`
|
||||
Tradable bool `json:"tradeable"`
|
||||
MarginLevels []struct {
|
||||
Contracts float64 `json:"contracts"`
|
||||
InitialMargin float64 `json:"initialMargin"`
|
||||
@@ -264,34 +266,34 @@ type FuturesInstrumentData struct {
|
||||
// FuturesTradeHistoryData stores trade history data for futures
|
||||
type FuturesTradeHistoryData struct {
|
||||
History []struct {
|
||||
Time string `json:"time"`
|
||||
TradeID int64 `json:"trade_id"`
|
||||
Price float64 `json:"price"`
|
||||
Size float64 `json:"size"`
|
||||
Side string `json:"side"`
|
||||
TradeType string `json:"type"`
|
||||
Time time.Time `json:"time"`
|
||||
TradeID int64 `json:"trade_id"`
|
||||
Price float64 `json:"price"`
|
||||
Size float64 `json:"size"`
|
||||
Side string `json:"side"`
|
||||
TradeType string `json:"type"`
|
||||
} `json:"history"`
|
||||
}
|
||||
|
||||
// FuturesTickersData stores info for futures tickers
|
||||
type FuturesTickersData struct {
|
||||
Tickers []FuturesTicker `json:"tickers"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// FuturesTickerData stores info for futures ticker
|
||||
type FuturesTickerData struct {
|
||||
Ticker FuturesTicker `json:"ticker"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// FuturesEditedOrderData stores an edited order's data
|
||||
type FuturesEditedOrderData struct {
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
EditStatus struct {
|
||||
Status string `json:"status"`
|
||||
OrderID string `json:"orderId"`
|
||||
ReceivedTime string `json:"receivedTime"`
|
||||
Status string `json:"status"`
|
||||
OrderID string `json:"orderId"`
|
||||
ReceivedTime time.Time `json:"receivedTime"`
|
||||
OrderEvents []struct {
|
||||
Old FuturesOrderData `json:"old"`
|
||||
New FuturesOrderData `json:"new"`
|
||||
@@ -303,34 +305,34 @@ type FuturesEditedOrderData struct {
|
||||
|
||||
// FuturesTicker holds futures ticker data
|
||||
type FuturesTicker struct {
|
||||
Tag string `json:"tag"`
|
||||
Pair string `json:"pair"`
|
||||
Symbol string `json:"symbol"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
Bid float64 `json:"bid"`
|
||||
BidSize float64 `json:"bidSize"`
|
||||
Ask float64 `json:"ask"`
|
||||
AskSize float64 `json:"askSize"`
|
||||
Vol24h float64 `json:"vol24h"`
|
||||
OpenInterest float64 `json:"openInterest"`
|
||||
Open24H float64 `json:"open24h"`
|
||||
Last float64 `json:"last"`
|
||||
LastTime string `json:"lastTime"`
|
||||
LastSize float64 `json:"lastSize"`
|
||||
Suspended bool `json:"suspended"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
FundingRatePrediction float64 `json:"fundingRatePrediction"`
|
||||
IndexPrice float64 `json:"indexPrice"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
Change24H float64 `json:"change24h"`
|
||||
Tag string `json:"tag"`
|
||||
Pair string `json:"pair"`
|
||||
Symbol string `json:"symbol"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
Bid float64 `json:"bid"`
|
||||
BidSize float64 `json:"bidSize"`
|
||||
Ask float64 `json:"ask"`
|
||||
AskSize float64 `json:"askSize"`
|
||||
Vol24h float64 `json:"vol24h"`
|
||||
OpenInterest float64 `json:"openInterest"`
|
||||
Open24H float64 `json:"open24h"`
|
||||
Last float64 `json:"last"`
|
||||
LastTime time.Time `json:"lastTime"`
|
||||
LastSize float64 `json:"lastSize"`
|
||||
Suspended bool `json:"suspended"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
FundingRatePrediction float64 `json:"fundingRatePrediction"`
|
||||
IndexPrice float64 `json:"indexPrice"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
Change24H float64 `json:"change24h"`
|
||||
}
|
||||
|
||||
// FuturesSendOrderData stores send order data
|
||||
type FuturesSendOrderData struct {
|
||||
SendStatus struct {
|
||||
OrderID string `json:"order_id"`
|
||||
Status string `json:"status"`
|
||||
ReceivedTime string `json:"receivedTime"`
|
||||
OrderID string `json:"order_id"`
|
||||
Status string `json:"status"`
|
||||
ReceivedTime time.Time `json:"receivedTime"`
|
||||
OrderEvents []struct {
|
||||
UID string `json:"uid"`
|
||||
Order FuturesOrderData `json:"order"`
|
||||
@@ -338,71 +340,71 @@ type FuturesSendOrderData struct {
|
||||
DataType string `json:"type"`
|
||||
} `json:"orderEvents"`
|
||||
} `json:"sendStatus"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// FuturesOrderData stores order data
|
||||
type FuturesOrderData struct {
|
||||
OrderID string `json:"orderId"`
|
||||
ClientOrderID string `json:"cliOrderId"`
|
||||
OrderType string `json:"type"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Quantity float64 `json:"quantity"`
|
||||
Filled float64 `json:"filled"`
|
||||
LimitPrice float64 `json:"limitPrice"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
LastUpdateTimestamp string `json:"lastUpdateTimestamp"`
|
||||
OrderID string `json:"orderId"`
|
||||
ClientOrderID string `json:"cliOrderId"`
|
||||
OrderType string `json:"type"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Quantity float64 `json:"quantity"`
|
||||
Filled float64 `json:"filled"`
|
||||
LimitPrice float64 `json:"limitPrice"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
LastUpdateTimestamp time.Time `json:"lastUpdateTimestamp"`
|
||||
}
|
||||
|
||||
// FuturesCancelOrderData stores cancel order data for futures
|
||||
type FuturesCancelOrderData struct {
|
||||
CancelStatus struct {
|
||||
Status string `json:"status"`
|
||||
OrderID string `json:"order_id"`
|
||||
ReceivedTime string `json:"receivedTime"`
|
||||
Status string `json:"status"`
|
||||
OrderID string `json:"order_id"`
|
||||
ReceivedTime time.Time `json:"receivedTime"`
|
||||
OrderEvents []struct {
|
||||
UID string `json:"uid"`
|
||||
Order FuturesOrderData `json:"order"`
|
||||
DataType string `json:"type"`
|
||||
} `json:"orderEvents"`
|
||||
} `json:"cancelStatus"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// FuturesFillsData stores fills data
|
||||
type FuturesFillsData struct {
|
||||
Fills []struct {
|
||||
FillID string `json:"fill_id"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"buy"`
|
||||
OrderID string `json:"order_id"`
|
||||
Size float64 `json:"size"`
|
||||
Price float64 `json:"price"`
|
||||
FillTime string `json:"fillTime"`
|
||||
FillType string `json:"fillType"`
|
||||
FillID string `json:"fill_id"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
OrderID string `json:"order_id"`
|
||||
Size float64 `json:"size"`
|
||||
Price float64 `json:"price"`
|
||||
FillTime time.Time `json:"fillTime"`
|
||||
FillType string `json:"fillType"`
|
||||
} `json:"fills"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// FuturesTransferData stores transfer data
|
||||
type FuturesTransferData struct {
|
||||
Result string `json:"result"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
Result string `json:"result"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// FuturesOpenPositions stores open positions data for futures
|
||||
type FuturesOpenPositions struct {
|
||||
OpenPositions []struct {
|
||||
Side string `json:"side"`
|
||||
Symbol string `json:"symbol"`
|
||||
Price float64 `json:"price"`
|
||||
FillTime string `json:"fillTime"`
|
||||
Size float64 `json:"size"`
|
||||
UnrealizedFunding float64 `json:"unrealizedFunding"`
|
||||
Side string `json:"side"`
|
||||
Symbol string `json:"symbol"`
|
||||
Price float64 `json:"price"`
|
||||
FillTime time.Time `json:"fillTime"`
|
||||
Size float64 `json:"size"`
|
||||
UnrealizedFunding float64 `json:"unrealizedFunding"`
|
||||
} `json:"openPositions"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// FuturesNotificationData stores notification data
|
||||
@@ -413,7 +415,7 @@ type FuturesNotificationData struct {
|
||||
Note string `json:"note"`
|
||||
EffectiveTime string `json:"effectiveTime"`
|
||||
} `json:"notifications"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// FuturesAccountsData stores account data
|
||||
@@ -449,9 +451,9 @@ type AccountsData struct {
|
||||
// CancelAllOrdersData stores order data for all cancelled orders
|
||||
type CancelAllOrdersData struct {
|
||||
CancelStatus struct {
|
||||
ReceivedTime string `json:"receivedTime"`
|
||||
CancelOnly string `json:"cancelOnly"`
|
||||
Status string `json:"status"`
|
||||
ReceivedTime time.Time `json:"receivedTime"`
|
||||
CancelOnly string `json:"cancelOnly"`
|
||||
Status string `json:"status"`
|
||||
CancelledOrders []struct {
|
||||
OrderID string `json:"order_id"`
|
||||
} `json:"cancelledOrders"`
|
||||
@@ -461,17 +463,17 @@ type CancelAllOrdersData struct {
|
||||
Order FuturesOrderData `json:"order"`
|
||||
DataType string `json:"type"`
|
||||
} `json:"cancelStatus"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// CancelOrdersAfterData stores data of all orders after a certain time that are cancelled
|
||||
type CancelOrdersAfterData struct {
|
||||
Result string `json:"result"`
|
||||
Status struct {
|
||||
CurrentTime string `json:"currentTime"`
|
||||
TriggerTime string `json:"triggerTime"`
|
||||
CurrentTime time.Time `json:"currentTime"`
|
||||
TriggerTime time.Time `json:"triggerTime"`
|
||||
} `json:"status"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// RecentOrderData stores order data of a recent order
|
||||
@@ -491,20 +493,20 @@ type RecentOrderData struct {
|
||||
|
||||
// FOpenOrdersData stores open orders data for futures
|
||||
type FOpenOrdersData struct {
|
||||
OrderID string `json:"order_id"`
|
||||
ClientOrderID string `json:"cliOrdId"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
OrderType string `json:"orderType"`
|
||||
LimitPrice float64 `json:"limitPrice"`
|
||||
StopPrice float64 `json:"stopPrice"`
|
||||
UnfilledSize float64 `json:"unfilledSize"`
|
||||
ReceivedTime string `json:"receivedTime"`
|
||||
Status string `json:"status"`
|
||||
FilledSize float64 `json:"filledSize"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
TriggerSignal string `json:"triggerSignal"`
|
||||
LastUpdateTime string `json:"lastUpdateTime"`
|
||||
OrderID string `json:"order_id"`
|
||||
ClientOrderID string `json:"cliOrdId"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
OrderType string `json:"orderType"`
|
||||
LimitPrice float64 `json:"limitPrice"`
|
||||
StopPrice float64 `json:"stopPrice"`
|
||||
UnfilledSize float64 `json:"unfilledSize"`
|
||||
ReceivedTime time.Time `json:"receivedTime"`
|
||||
Status string `json:"status"`
|
||||
FilledSize float64 `json:"filledSize"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
TriggerSignal string `json:"triggerSignal"`
|
||||
LastUpdateTime time.Time `json:"lastUpdateTime"`
|
||||
}
|
||||
|
||||
// FuturesRecentOrdersData stores recent orders data
|
||||
@@ -540,17 +542,17 @@ type FuturesRecentOrdersData struct {
|
||||
|
||||
// BatchOrderData stores batch order data
|
||||
type BatchOrderData struct {
|
||||
Result string `json:"result"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
Result string `json:"result"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
BatchStatus []struct {
|
||||
Status string `json:"status"`
|
||||
OrderTag string `json:"order_tag"`
|
||||
OrderID string `json:"order_id"`
|
||||
DateTimeReceived string `json:"dateTimeReceived"`
|
||||
Status string `json:"status"`
|
||||
OrderTag string `json:"order_tag"`
|
||||
OrderID string `json:"order_id"`
|
||||
DateTimeReceived time.Time `json:"dateTimeReceived"`
|
||||
OrderEvents []struct {
|
||||
OrderPlaced FuturesOrderData `json:"orderPlaced"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
OldEditedOrder FuturesOrderData `json:"old"`
|
||||
NewEditedOrder FuturesOrderData `json:"new"`
|
||||
UID string `json:"uid"`
|
||||
@@ -584,7 +586,7 @@ type ExecutionData struct {
|
||||
type FuturesOpenOrdersData struct {
|
||||
Result string `json:"result"`
|
||||
OpenOrders []FOpenOrdersData `json:"openOrders"`
|
||||
ServerTime string `json:"serverTime"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
// FuturesPublicTrades returns public trade data
|
||||
@@ -604,34 +606,34 @@ type FuturesPublicTrades struct {
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
TakerOrder FutureTradeOrder `json:"takerOrder"`
|
||||
TakerOrderData FuturesTradeOrderData `json:"takerOrderData"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Timestamp types.Time `json:"timestamp"`
|
||||
UID string `json:"uid"`
|
||||
UsdValue float64 `json:"usdValue,string"`
|
||||
} `json:"execution"`
|
||||
TakerReducedQuantity string `json:"takerReducedQuantity"`
|
||||
} `json:"execution"`
|
||||
} `json:"event"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
UID string `json:"uid"`
|
||||
Timestamp types.Time `json:"timestamp"`
|
||||
UID string `json:"uid"`
|
||||
} `json:"elements"`
|
||||
Len int64 `json:"len"`
|
||||
}
|
||||
|
||||
// FutureTradeOrder holds details about the order for a futures trade
|
||||
type FutureTradeOrder struct {
|
||||
AccountUID string `json:"accountUid"`
|
||||
ClientID string `json:"clientId"`
|
||||
Direction string `json:"direction"`
|
||||
Filled string `json:"filled"`
|
||||
LastUpdateTimestamp int64 `json:"lastUpdateTimestamp"`
|
||||
LimitPrice float64 `json:"limitPrice,string"`
|
||||
OrderType string `json:"orderType"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
SpotData string `json:"spotData"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Tradeable string `json:"tradeable"`
|
||||
UID string `json:"uid"`
|
||||
AccountUID string `json:"accountUid"`
|
||||
ClientID string `json:"clientId"`
|
||||
Direction string `json:"direction"`
|
||||
Filled string `json:"filled"`
|
||||
LastUpdateTimestamp types.Time `json:"lastUpdateTimestamp"`
|
||||
LimitPrice float64 `json:"limitPrice,string"`
|
||||
OrderType string `json:"orderType"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
SpotData string `json:"spotData"`
|
||||
Timestamp types.Time `json:"timestamp"`
|
||||
Tradeable string `json:"tradeable"`
|
||||
UID string `json:"uid"`
|
||||
}
|
||||
|
||||
// FuturesTradeOrderData holds additional order details for a futures trade order
|
||||
@@ -648,10 +650,10 @@ type FuturesCandles struct {
|
||||
|
||||
// FuturesCandle is an individual candle
|
||||
type FuturesCandle struct {
|
||||
Close float64 `json:"close,string"`
|
||||
High float64 `json:"high,string"`
|
||||
Low float64 `json:"low,string"`
|
||||
Open float64 `json:"open,string"`
|
||||
Time int64 `json:"time"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
Close float64 `json:"close,string"`
|
||||
High float64 `json:"high,string"`
|
||||
Low float64 `json:"low,string"`
|
||||
Open float64 `json:"open,string"`
|
||||
Time types.Time `json:"time"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
}
|
||||
|
||||
@@ -1283,7 +1283,7 @@ func TestWsOpenOrders(t *testing.T) {
|
||||
assert.Equal(t, order.Pending, v.Status, "order status")
|
||||
assert.Equal(t, 0.0, v.Price, "price")
|
||||
assert.Equal(t, 0.0001, v.Amount, "amount")
|
||||
assert.Equal(t, time.UnixMicro(1692851641361371).UTC(), v.Date, "Date")
|
||||
assert.Equal(t, time.UnixMicro(1692851641361371).UTC(), v.Date.UTC(), "Date")
|
||||
case 4:
|
||||
assert.Equal(t, "OKB55A-UEMMN-YUXM2A", v.OrderID, "OrderID")
|
||||
assert.Equal(t, order.Open, v.Status, "order status")
|
||||
@@ -1300,7 +1300,7 @@ func TestWsOpenOrders(t *testing.T) {
|
||||
assert.Equal(t, 0.0001, v.ExecutedAmount, "ExecutedAmount")
|
||||
assert.Equal(t, 26425.2, v.AverageExecutedPrice, "AverageExecutedPrice")
|
||||
assert.Equal(t, 0.00687, v.Fee, "Fee")
|
||||
assert.Equal(t, time.UnixMicro(1692851641361447).UTC(), v.LastUpdated, "LastUpdated")
|
||||
assert.Equal(t, time.UnixMicro(1692851641361447).UTC(), v.LastUpdated.UTC(), "LastUpdated")
|
||||
case 1:
|
||||
assert.Equal(t, "OGTT3Y-C6I3P-XRI6HR", v.OrderID, "OrderID")
|
||||
assert.Equal(t, order.UnknownStatus, v.Status, "order status")
|
||||
@@ -1310,7 +1310,7 @@ func TestWsOpenOrders(t *testing.T) {
|
||||
case 0:
|
||||
assert.Equal(t, "OGTT3Y-C6I3P-XRI6HR", v.OrderID, "OrderID")
|
||||
assert.Equal(t, order.Closed, v.Status, "order status")
|
||||
assert.Equal(t, time.UnixMicro(1692675961789052).UTC(), v.LastUpdated, "LastUpdated")
|
||||
assert.Equal(t, time.UnixMicro(1692675961789052).UTC(), v.LastUpdated.UTC(), "LastUpdated")
|
||||
assert.Equal(t, 10.00345345, v.ExecutedAmount, "ExecutedAmount")
|
||||
assert.Equal(t, 0.001, v.Fee, "Fee")
|
||||
assert.Equal(t, 34.5, v.AverageExecutedPrice, "AverageExecutedPrice")
|
||||
@@ -1424,7 +1424,7 @@ func TestGetCharts(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, resp.Candles)
|
||||
|
||||
end := time.UnixMilli(resp.Candles[0].Time)
|
||||
end := resp.Candles[0].Time.Time()
|
||||
_, err = k.GetFuturesCharts(t.Context(), "1d", "spot", futuresTestPair, end.Add(-time.Hour*24*7), end)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -229,13 +229,13 @@ type TradeBalanceInfo struct {
|
||||
|
||||
// OrderInfo type
|
||||
type OrderInfo struct {
|
||||
RefID string `json:"refid"`
|
||||
UserRef int32 `json:"userref"`
|
||||
Status string `json:"status"`
|
||||
OpenTime float64 `json:"opentm"`
|
||||
CloseTime float64 `json:"closetm"`
|
||||
StartTime float64 `json:"starttm"`
|
||||
ExpireTime float64 `json:"expiretm"`
|
||||
RefID string `json:"refid"`
|
||||
UserRef int32 `json:"userref"`
|
||||
Status string `json:"status"`
|
||||
OpenTime types.Time `json:"opentm"`
|
||||
CloseTime types.Time `json:"closetm"`
|
||||
StartTime types.Time `json:"starttm"`
|
||||
ExpireTime types.Time `json:"expiretm"`
|
||||
Description struct {
|
||||
Pair string `json:"pair"`
|
||||
Type string `json:"type"`
|
||||
@@ -303,44 +303,44 @@ type TradesHistory struct {
|
||||
|
||||
// TradeInfo type
|
||||
type TradeInfo struct {
|
||||
OrderTxID string `json:"ordertxid"`
|
||||
Pair string `json:"pair"`
|
||||
Time float64 `json:"time"`
|
||||
Type string `json:"type"`
|
||||
OrderType string `json:"ordertype"`
|
||||
Price float64 `json:"price,string"`
|
||||
Cost float64 `json:"cost,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Volume float64 `json:"vol,string"`
|
||||
Margin float64 `json:"margin,string"`
|
||||
Misc string `json:"misc"`
|
||||
PosTxID string `json:"postxid"`
|
||||
ClosedPositionAveragePrice float64 `json:"cprice,string"`
|
||||
ClosedPositionFee float64 `json:"cfee,string"`
|
||||
ClosedPositionVolume float64 `json:"cvol,string"`
|
||||
ClosedPositionMargin float64 `json:"cmargin,string"`
|
||||
Trades []string `json:"trades"`
|
||||
PosStatus string `json:"posstatus"`
|
||||
OrderTxID string `json:"ordertxid"`
|
||||
Pair string `json:"pair"`
|
||||
Time types.Time `json:"time"`
|
||||
Type string `json:"type"`
|
||||
OrderType string `json:"ordertype"`
|
||||
Price float64 `json:"price,string"`
|
||||
Cost float64 `json:"cost,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Volume float64 `json:"vol,string"`
|
||||
Margin float64 `json:"margin,string"`
|
||||
Misc string `json:"misc"`
|
||||
PosTxID string `json:"postxid"`
|
||||
ClosedPositionAveragePrice float64 `json:"cprice,string"`
|
||||
ClosedPositionFee float64 `json:"cfee,string"`
|
||||
ClosedPositionVolume float64 `json:"cvol,string"`
|
||||
ClosedPositionMargin float64 `json:"cmargin,string"`
|
||||
Trades []string `json:"trades"`
|
||||
PosStatus string `json:"posstatus"`
|
||||
}
|
||||
|
||||
// Position holds the opened position
|
||||
type Position struct {
|
||||
Ordertxid string `json:"ordertxid"`
|
||||
Pair string `json:"pair"`
|
||||
Time float64 `json:"time"`
|
||||
Type string `json:"type"`
|
||||
OrderType string `json:"ordertype"`
|
||||
Cost float64 `json:"cost,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Volume float64 `json:"vol,string"`
|
||||
VolumeClosed float64 `json:"vol_closed,string"`
|
||||
Margin float64 `json:"margin,string"`
|
||||
RolloverTime int64 `json:"rollovertm,string"`
|
||||
Misc string `json:"misc"`
|
||||
OrderFlags string `json:"oflags"`
|
||||
PositionStatus string `json:"posstatus"`
|
||||
Net string `json:"net"`
|
||||
Terms string `json:"terms"`
|
||||
Ordertxid string `json:"ordertxid"`
|
||||
Pair string `json:"pair"`
|
||||
Time types.Time `json:"time"`
|
||||
Type string `json:"type"`
|
||||
OrderType string `json:"ordertype"`
|
||||
Cost float64 `json:"cost,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Volume float64 `json:"vol,string"`
|
||||
VolumeClosed float64 `json:"vol_closed,string"`
|
||||
Margin float64 `json:"margin,string"`
|
||||
RolloverTime int64 `json:"rollovertm,string"`
|
||||
Misc string `json:"misc"`
|
||||
OrderFlags string `json:"oflags"`
|
||||
PositionStatus string `json:"posstatus"`
|
||||
Net string `json:"net"`
|
||||
Terms string `json:"terms"`
|
||||
}
|
||||
|
||||
// GetLedgersOptions type
|
||||
@@ -361,14 +361,14 @@ type Ledgers struct {
|
||||
|
||||
// LedgerInfo type
|
||||
type LedgerInfo struct {
|
||||
Refid string `json:"refid"`
|
||||
Time float64 `json:"time"`
|
||||
Type string `json:"type"`
|
||||
Aclass string `json:"aclass"`
|
||||
Asset string `json:"asset"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
Refid string `json:"refid"`
|
||||
Time types.Time `json:"time"`
|
||||
Type string `json:"type"`
|
||||
Aclass string `json:"aclass"`
|
||||
Asset string `json:"asset"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
}
|
||||
|
||||
// TradeVolumeResponse type
|
||||
@@ -482,16 +482,16 @@ type DepositAddress struct {
|
||||
|
||||
// WithdrawStatusResponse defines a withdrawal status response
|
||||
type WithdrawStatusResponse struct {
|
||||
Method string `json:"method"`
|
||||
Aclass string `json:"aclass"`
|
||||
Asset string `json:"asset"`
|
||||
Refid string `json:"refid"`
|
||||
TxID string `json:"txid"`
|
||||
Info string `json:"info"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Time float64 `json:"time"`
|
||||
Status string `json:"status"`
|
||||
Method string `json:"method"`
|
||||
Aclass string `json:"aclass"`
|
||||
Asset string `json:"asset"`
|
||||
Refid string `json:"refid"`
|
||||
TxID string `json:"txid"`
|
||||
Info string `json:"info"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Time types.Time `json:"time"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
// WebsocketSubRequest contains request data for Subscribe/Unsubscribe to channels
|
||||
@@ -552,22 +552,22 @@ type wsSystemStatus struct {
|
||||
|
||||
// WsOpenOrder contains all open order data from ws feed
|
||||
type WsOpenOrder struct {
|
||||
UserReferenceID int64 `json:"userref"`
|
||||
ExpireTime float64 `json:"expiretm,string"`
|
||||
LastUpdated float64 `json:"lastupdated,string"`
|
||||
OpenTime float64 `json:"opentm,string"`
|
||||
StartTime float64 `json:"starttm,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
LimitPrice float64 `json:"limitprice,string"`
|
||||
StopPrice float64 `json:"stopprice,string"`
|
||||
Volume float64 `json:"vol,string"`
|
||||
ExecutedVolume float64 `json:"vol_exec,string"`
|
||||
Cost float64 `json:"cost,string"`
|
||||
AveragePrice float64 `json:"avg_price,string"`
|
||||
Misc string `json:"misc"`
|
||||
OFlags string `json:"oflags"`
|
||||
RefID string `json:"refid"`
|
||||
Status string `json:"status"`
|
||||
UserReferenceID int64 `json:"userref"`
|
||||
ExpireTime types.Time `json:"expiretm"`
|
||||
LastUpdated types.Time `json:"lastupdated"`
|
||||
OpenTime types.Time `json:"opentm"`
|
||||
StartTime types.Time `json:"starttm"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
LimitPrice float64 `json:"limitprice,string"`
|
||||
StopPrice float64 `json:"stopprice,string"`
|
||||
Volume float64 `json:"vol,string"`
|
||||
ExecutedVolume float64 `json:"vol_exec,string"`
|
||||
Cost float64 `json:"cost,string"`
|
||||
AveragePrice float64 `json:"avg_price,string"`
|
||||
Misc string `json:"misc"`
|
||||
OFlags string `json:"oflags"`
|
||||
RefID string `json:"refid"`
|
||||
Status string `json:"status"`
|
||||
Description struct {
|
||||
Close string `json:"close"`
|
||||
Price float64 `json:"price,string"`
|
||||
@@ -582,32 +582,32 @@ type WsOpenOrder struct {
|
||||
|
||||
// WsOwnTrade ws auth owntrade data
|
||||
type WsOwnTrade struct {
|
||||
Cost float64 `json:"cost,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Margin float64 `json:"margin,string"`
|
||||
OrderTransactionID string `json:"ordertxid"`
|
||||
OrderType string `json:"ordertype"`
|
||||
Pair string `json:"pair"`
|
||||
PostTransactionID string `json:"postxid"`
|
||||
Price float64 `json:"price,string"`
|
||||
Time float64 `json:"time,string"`
|
||||
Type string `json:"type"`
|
||||
Vol float64 `json:"vol,string"`
|
||||
Cost float64 `json:"cost,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Margin float64 `json:"margin,string"`
|
||||
OrderTransactionID string `json:"ordertxid"`
|
||||
OrderType string `json:"ordertype"`
|
||||
Pair string `json:"pair"`
|
||||
PostTransactionID string `json:"postxid"`
|
||||
Price float64 `json:"price,string"`
|
||||
Time types.Time `json:"time"`
|
||||
Type string `json:"type"`
|
||||
Vol float64 `json:"vol,string"`
|
||||
}
|
||||
|
||||
// WsOpenOrders ws auth open order data
|
||||
type WsOpenOrders struct {
|
||||
Cost float64 `json:"cost,string"`
|
||||
Description WsOpenOrderDescription `json:"descr"`
|
||||
ExpireTime time.Time `json:"expiretm"`
|
||||
ExpireTime types.Time `json:"expiretm"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
LimitPrice float64 `json:"limitprice,string"`
|
||||
Misc string `json:"misc"`
|
||||
OFlags string `json:"oflags"`
|
||||
OpenTime time.Time `json:"opentm"`
|
||||
OpenTime types.Time `json:"opentm"`
|
||||
Price float64 `json:"price,string"`
|
||||
RefID string `json:"refid"`
|
||||
StartTime time.Time `json:"starttm"`
|
||||
StartTime types.Time `json:"starttm"`
|
||||
Status string `json:"status"`
|
||||
StopPrice float64 `json:"stopprice,string"`
|
||||
UserReference float64 `json:"userref"`
|
||||
|
||||
@@ -322,7 +322,7 @@ func (k *Kraken) wsProcessOwnTrades(ownOrders any) error {
|
||||
TID: key,
|
||||
Type: oType,
|
||||
Side: oSide,
|
||||
Timestamp: convert.TimeFromUnixTimestampDecimal(val.Time),
|
||||
Timestamp: val.Time.Time(),
|
||||
}
|
||||
k.Websocket.DataHandler <- &order.Detail{
|
||||
Exchange: k.Name,
|
||||
@@ -357,8 +357,8 @@ func (k *Kraken) wsProcessOpenOrders(ownOrders any) error {
|
||||
LimitPriceUpper: val.LimitPrice,
|
||||
ExecutedAmount: val.ExecutedVolume,
|
||||
Fee: val.Fee,
|
||||
Date: convert.TimeFromUnixTimestampDecimal(val.OpenTime).Truncate(time.Microsecond),
|
||||
LastUpdated: convert.TimeFromUnixTimestampDecimal(val.LastUpdated).Truncate(time.Microsecond),
|
||||
Date: val.OpenTime.Time(),
|
||||
LastUpdated: val.LastUpdated.Time(),
|
||||
}
|
||||
|
||||
if val.Status != "" {
|
||||
|
||||
@@ -603,7 +603,7 @@ func (k *Kraken) GetWithdrawalsHistory(ctx context.Context, c currency.Code, _ a
|
||||
resp[i] = exchange.WithdrawalHistory{
|
||||
Status: withdrawals[i].Status,
|
||||
TransferID: withdrawals[i].Refid,
|
||||
Timestamp: time.Unix(int64(withdrawals[i].Time), 0),
|
||||
Timestamp: withdrawals[i].Time.Time(),
|
||||
Amount: withdrawals[i].Amount,
|
||||
Fee: withdrawals[i].Fee,
|
||||
CryptoToAddress: withdrawals[i].Info,
|
||||
@@ -665,7 +665,7 @@ func (k *Kraken) GetRecentTrades(ctx context.Context, p currency.Pair, assetType
|
||||
Side: side,
|
||||
Price: tradeData.Elements[i].ExecutionEvent.OuterExecutionHolder.Execution.MakerOrder.LimitPrice,
|
||||
Amount: tradeData.Elements[i].ExecutionEvent.OuterExecutionHolder.Execution.MakerOrder.Quantity,
|
||||
Timestamp: time.UnixMilli(tradeData.Elements[i].ExecutionEvent.OuterExecutionHolder.Execution.MakerOrder.Timestamp),
|
||||
Timestamp: tradeData.Elements[i].ExecutionEvent.OuterExecutionHolder.Execution.MakerOrder.Timestamp.Time(),
|
||||
})
|
||||
}
|
||||
default:
|
||||
@@ -941,8 +941,8 @@ func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa
|
||||
Pair: p,
|
||||
Side: side,
|
||||
Type: oType,
|
||||
Date: convert.TimeFromUnixTimestampDecimal(orderInfo.OpenTime),
|
||||
CloseTime: convert.TimeFromUnixTimestampDecimal(orderInfo.CloseTime),
|
||||
Date: orderInfo.OpenTime.Time(),
|
||||
CloseTime: orderInfo.CloseTime.Time(),
|
||||
Status: status,
|
||||
Price: price,
|
||||
Amount: orderInfo.Volume,
|
||||
@@ -974,17 +974,13 @@ func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pa
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
timeVar, err := time.Parse(krakenFormat, orderInfo.Fills[y].FillTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orderDetail = order.Detail{
|
||||
OrderID: orderID,
|
||||
Price: orderInfo.Fills[y].Price,
|
||||
Amount: orderInfo.Fills[y].Size,
|
||||
Side: oSide,
|
||||
Type: fillOrderType,
|
||||
Date: timeVar,
|
||||
Date: orderInfo.Fills[y].FillTime,
|
||||
Pair: pair,
|
||||
Exchange: k.Name,
|
||||
AssetType: asset.Futures,
|
||||
@@ -1143,7 +1139,7 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque
|
||||
RemainingAmount: resp.Open[i].Volume - resp.Open[i].VolumeExecuted,
|
||||
ExecutedAmount: resp.Open[i].VolumeExecuted,
|
||||
Exchange: k.Name,
|
||||
Date: convert.TimeFromUnixTimestampDecimal(resp.Open[i].OpenTime),
|
||||
Date: resp.Open[i].OpenTime.Time(),
|
||||
Price: resp.Open[i].Description.Price,
|
||||
Side: side,
|
||||
Type: orderType,
|
||||
@@ -1184,17 +1180,13 @@ func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.MultiOrderReque
|
||||
if err != nil {
|
||||
return orders, err
|
||||
}
|
||||
timeVar, err := time.Parse(krakenFormat, activeOrders.OpenOrders[a].ReceivedTime)
|
||||
if err != nil {
|
||||
return orders, err
|
||||
}
|
||||
orders = append(orders, order.Detail{
|
||||
OrderID: activeOrders.OpenOrders[a].OrderID,
|
||||
Price: activeOrders.OpenOrders[a].LimitPrice,
|
||||
Amount: activeOrders.OpenOrders[a].FilledSize,
|
||||
Side: oSide,
|
||||
Type: oType,
|
||||
Date: timeVar,
|
||||
Date: activeOrders.OpenOrders[a].ReceivedTime,
|
||||
Pair: fPair,
|
||||
Exchange: k.Name,
|
||||
AssetType: asset.Futures,
|
||||
@@ -1276,8 +1268,8 @@ func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.Mu
|
||||
Cost: resp.Closed[i].Cost,
|
||||
CostAsset: p.Quote,
|
||||
Exchange: k.Name,
|
||||
Date: convert.TimeFromUnixTimestampDecimal(resp.Closed[i].OpenTime),
|
||||
CloseTime: convert.TimeFromUnixTimestampDecimal(resp.Closed[i].CloseTime),
|
||||
Date: resp.Closed[i].OpenTime.Time(),
|
||||
CloseTime: resp.Closed[i].CloseTime.Time(),
|
||||
Price: resp.Closed[i].Description.Price,
|
||||
Side: side,
|
||||
Status: status,
|
||||
@@ -1615,20 +1607,14 @@ func (k *Kraken) GetFuturesContractDetails(ctx context.Context, item asset.Item)
|
||||
return nil, err
|
||||
}
|
||||
var s, e time.Time
|
||||
if result.Instruments[i].OpeningDate != "" {
|
||||
s, err = time.Parse(time.RFC3339, result.Instruments[i].OpeningDate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !result.Instruments[i].OpeningDate.IsZero() {
|
||||
s = result.Instruments[i].OpeningDate
|
||||
}
|
||||
var ct futures.ContractType
|
||||
if result.Instruments[i].LastTradingTime == "" || item == asset.PerpetualSwap {
|
||||
if result.Instruments[i].LastTradingTime.IsZero() || item == asset.PerpetualSwap {
|
||||
ct = futures.Perpetual
|
||||
} else {
|
||||
e, err = time.Parse(time.RFC3339, result.Instruments[i].LastTradingTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
e = result.Instruments[i].LastTradingTime
|
||||
switch {
|
||||
// three day is used for generosity for contract date ranges
|
||||
case e.Sub(s) <= kline.OneMonth.Duration()+kline.ThreeDay.Duration():
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -13,6 +14,8 @@ import (
|
||||
// format requirements.
|
||||
type Time time.Time
|
||||
|
||||
var errInvalidTimestampFormat = errors.New("invalid timestamp format")
|
||||
|
||||
// UnmarshalJSON deserializes json, and timestamp information.
|
||||
func (t *Time) UnmarshalJSON(data []byte) error {
|
||||
s := string(data)
|
||||
@@ -21,13 +24,16 @@ func (t *Time) UnmarshalJSON(data []byte) error {
|
||||
s = s[1 : len(s)-1]
|
||||
}
|
||||
|
||||
switch s {
|
||||
case "null", "0", "":
|
||||
if s == "" || s[0] == 'n' || s == "0" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if target := strings.Index(s, "."); target != -1 {
|
||||
s = s[:target] + s[target+1:]
|
||||
|
||||
if strings.Trim(s, "0") == "" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Expects a string of length 10 (seconds), 13 (milliseconds), 16 (microseconds), or 19 (nanoseconds) representing a Unix timestamp
|
||||
@@ -53,7 +59,7 @@ func (t *Time) UnmarshalJSON(data []byte) error {
|
||||
case 19:
|
||||
*t = Time(time.Unix(0, unixTS))
|
||||
default:
|
||||
return fmt.Errorf("cannot unmarshal %s into Time", data)
|
||||
return fmt.Errorf("%w: %q", errInvalidTimestampFormat, data)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -12,62 +12,47 @@ import (
|
||||
|
||||
func TestUnmarshalJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
var testTime Time
|
||||
|
||||
require.NoError(t, json.Unmarshal([]byte(`null`), &testTime))
|
||||
assert.Equal(t, time.Time{}, testTime.Time())
|
||||
|
||||
require.NoError(t, json.Unmarshal([]byte(`0`), &testTime))
|
||||
assert.Equal(t, time.Time{}, testTime.Time())
|
||||
|
||||
require.NoError(t, json.Unmarshal([]byte(`""`), &testTime))
|
||||
assert.Equal(t, time.Time{}, testTime.Time())
|
||||
|
||||
require.NoError(t, json.Unmarshal([]byte(`"0"`), &testTime))
|
||||
assert.Equal(t, time.Time{}, testTime.Time())
|
||||
|
||||
// seconds
|
||||
require.NoError(t, json.Unmarshal([]byte(`"1628736847"`), &testTime))
|
||||
assert.Equal(t, time.Unix(1628736847, 0), testTime.Time())
|
||||
|
||||
// milliseconds
|
||||
require.NoError(t, json.Unmarshal([]byte(`"1726104395.5"`), &testTime))
|
||||
assert.Equal(t, time.UnixMilli(1726104395500), testTime.Time())
|
||||
|
||||
require.NoError(t, json.Unmarshal([]byte(`"1726104395.56"`), &testTime))
|
||||
assert.Equal(t, time.UnixMilli(1726104395560), testTime.Time())
|
||||
|
||||
require.NoError(t, json.Unmarshal([]byte(`"1628736847325"`), &testTime))
|
||||
assert.Equal(t, time.UnixMilli(1628736847325), testTime.Time())
|
||||
|
||||
// microseconds
|
||||
require.NoError(t, json.Unmarshal([]byte(`"1628736847325123"`), &testTime))
|
||||
assert.Equal(t, time.UnixMicro(1628736847325123), testTime.Time())
|
||||
|
||||
require.NoError(t, json.Unmarshal([]byte(`"1726106210903.0"`), &testTime))
|
||||
assert.Equal(t, time.UnixMicro(1726106210903000), testTime.Time())
|
||||
|
||||
require.NoError(t, json.Unmarshal([]byte(`"1747278712.09328"`), &testTime))
|
||||
assert.Equal(t, time.UnixMicro(1747278712093280), testTime.Time())
|
||||
|
||||
// nanoseconds
|
||||
require.NoError(t, json.Unmarshal([]byte(`"1606292218213.4578"`), &testTime))
|
||||
assert.Equal(t, time.Unix(0, 1606292218213457800), testTime.Time())
|
||||
|
||||
require.NoError(t, json.Unmarshal([]byte(`"1606292218213457800"`), &testTime))
|
||||
assert.Equal(t, time.Unix(0, 1606292218213457800), testTime.Time())
|
||||
|
||||
require.ErrorIs(t, json.Unmarshal([]byte(`"blurp"`), &testTime), strconv.ErrSyntax)
|
||||
require.Error(t, json.Unmarshal([]byte(`"123456"`), &testTime))
|
||||
|
||||
// Captures bad syntax when type should be time.Time (RFC3339)
|
||||
require.ErrorIs(t, json.Unmarshal([]byte(`"2025-03-28T08:00:00Z"`), &testTime), strconv.ErrSyntax)
|
||||
// parse int failure
|
||||
require.ErrorIs(t, json.Unmarshal([]byte(`"1606292218213.45.8"`), &testTime), strconv.ErrSyntax)
|
||||
for _, tc := range []struct {
|
||||
input string
|
||||
want time.Time
|
||||
expError error
|
||||
}{
|
||||
{"null", time.Time{}, nil},
|
||||
{"0", time.Time{}, nil},
|
||||
{`""`, time.Time{}, nil},
|
||||
{`"0"`, time.Time{}, nil},
|
||||
{`"0.0"`, time.Time{}, nil},
|
||||
{`"0.00000"`, time.Time{}, nil},
|
||||
{`"0.0.0.0"`, time.Time{}, strconv.ErrSyntax},
|
||||
{`"0.1"`, time.Time{}, errInvalidTimestampFormat},
|
||||
{`"1628736847"`, time.Unix(1628736847, 0), nil},
|
||||
{`"1726104395.5"`, time.UnixMilli(1726104395500), nil},
|
||||
{`"1726104395.56"`, time.UnixMilli(1726104395560), nil},
|
||||
{`"1628736847325"`, time.UnixMilli(1628736847325), nil},
|
||||
{`"1628736847325123"`, time.UnixMicro(1628736847325123), nil},
|
||||
{`"1726106210903.0"`, time.UnixMicro(1726106210903000), nil},
|
||||
{`"1747278712.09328"`, time.UnixMicro(1747278712093280), nil},
|
||||
{`"1606292218213.4578"`, time.Unix(0, 1606292218213457800), nil},
|
||||
{`"1560516023.070651"`, time.Unix(0, 1560516023070651000), nil},
|
||||
{`"1606292218213457800"`, time.Unix(0, 1606292218213457800), nil},
|
||||
{`"blurp"`, time.Time{}, strconv.ErrSyntax},
|
||||
{`"123456"`, time.Time{}, errInvalidTimestampFormat},
|
||||
{`"2025-03-28T08:00:00Z"`, time.Time{}, strconv.ErrSyntax}, // RFC3339 format
|
||||
{`"1606292218213.45.8"`, time.Time{}, strconv.ErrSyntax}, // parse int failure
|
||||
} {
|
||||
t.Run(tc.input, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var testTime Time
|
||||
err := json.Unmarshal([]byte(tc.input), &testTime)
|
||||
require.ErrorIsf(t, err, tc.expError, "Unmarshal must not error for input %q", tc.input)
|
||||
assert.Equal(t, tc.want, testTime.Time())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 6152384 195.5 ns/op 168 B/op 2 allocs/op (current)
|
||||
// 5030734 240.1 ns/op 168 B/op 2 allocs/op (previous)
|
||||
// 3948978 303.5 ns/op 168 B/op 2 allocs/op (current) after more stringent checks
|
||||
// 6152384 195.5 ns/op 168 B/op 2 allocs/op (previous)
|
||||
func BenchmarkUnmarshalJSON(b *testing.B) {
|
||||
var testTime Time
|
||||
for b.Loop() {
|
||||
|
||||
Reference in New Issue
Block a user