mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
types: Add Time type from Gateio and share across codebase (#1648)
* consolidate type to types package and share across code base * rm convert type and convert codebase * rm irrelavant test cases * Fix tests * glorious nits * Update exchanges/gateio/gateio_types.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * thrasher: nits --------- Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
@@ -187,56 +186,3 @@ func InterfaceToStringOrZeroValue(r interface{}) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ExchangeTime provides timestamp to time conversion method.
|
||||
type ExchangeTime time.Time
|
||||
|
||||
// UnmarshalJSON is custom type json unmarshaller for ExchangeTime
|
||||
func (k *ExchangeTime) UnmarshalJSON(data []byte) error {
|
||||
var timestamp interface{}
|
||||
err := json.Unmarshal(data, ×tamp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var standard int64
|
||||
switch value := timestamp.(type) {
|
||||
case string:
|
||||
if value == "" {
|
||||
// Setting the time to zero value because some timestamp fields could return an empty string while there is no error
|
||||
// So, in such cases, Time returns zero timestamp.
|
||||
break
|
||||
}
|
||||
standard, err = strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case int64:
|
||||
standard = value
|
||||
case float64:
|
||||
// Warning: converting float64 to int64 instance may create loss of precision in the timestamp information.
|
||||
// be aware or consider customizing this section if found necessary.
|
||||
standard = int64(value)
|
||||
case nil:
|
||||
// for some exchange timestamp fields, if the timestamp information is not specified,
|
||||
// the data is 'nil' instead of zero value string or integer value.
|
||||
default:
|
||||
return fmt.Errorf("unsupported timestamp type %T", timestamp)
|
||||
}
|
||||
|
||||
switch {
|
||||
case standard == 0:
|
||||
*k = ExchangeTime(time.Time{})
|
||||
case standard >= 1e13:
|
||||
*k = ExchangeTime(time.Unix(standard/1e9, standard%1e9))
|
||||
case standard > 9999999999:
|
||||
*k = ExchangeTime(time.UnixMilli(standard))
|
||||
default:
|
||||
*k = ExchangeTime(time.Unix(standard, 0))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Time returns a time.Time instance from ExchangeTime instance object.
|
||||
func (k ExchangeTime) Time() time.Time {
|
||||
return time.Time(k)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -316,86 +315,3 @@ func TestInterfaceToStringOrZeroValue(t *testing.T) {
|
||||
t.Errorf("expected meow, got: %v", x)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExchangeTimeUnmarshalJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
unmarshaledResult := &struct {
|
||||
Timestamp ExchangeTime `json:"ts"`
|
||||
}{}
|
||||
data1 := `{"ts":""}`
|
||||
result := time.Time{}
|
||||
err := json.Unmarshal([]byte(data1), &unmarshaledResult)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
||||
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
||||
}
|
||||
data2 := `{"ts":"1685564775371"}`
|
||||
result = time.UnixMilli(1685564775371)
|
||||
err = json.Unmarshal([]byte(data2), &unmarshaledResult)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
||||
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
||||
}
|
||||
data3 := `{"ts":1685564775371}`
|
||||
err = json.Unmarshal([]byte(data3), &unmarshaledResult)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
||||
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
||||
}
|
||||
data4 := `{"ts":"1685564775"}`
|
||||
result = time.Unix(1685564775, 0)
|
||||
err = json.Unmarshal([]byte(data4), &unmarshaledResult)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
||||
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
||||
}
|
||||
data5 := `{"ts":1685564775}`
|
||||
err = json.Unmarshal([]byte(data5), &unmarshaledResult)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
||||
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
||||
}
|
||||
data6 := `{"ts":"1685564775371320000"}`
|
||||
result = time.Unix(int64(1685564775371320000)/1e9, int64(1685564775371320000)%1e9)
|
||||
err = json.Unmarshal([]byte(data6), &unmarshaledResult)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
||||
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
||||
}
|
||||
data7 := `{"ts":"abcdefg"}`
|
||||
err = json.Unmarshal([]byte(data7), &unmarshaledResult)
|
||||
if err == nil {
|
||||
t.Fatal("expecting error but found nil")
|
||||
}
|
||||
data8 := `{"ts":0}`
|
||||
result = time.Time{}
|
||||
err = json.Unmarshal([]byte(data8), &unmarshaledResult)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
||||
t.Errorf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
||||
}
|
||||
}
|
||||
|
||||
// 2239239 516.1 ns/op 424 B/op 9 allocs/op
|
||||
func BenchmarkExchangeTimeUnmarshaling(b *testing.B) {
|
||||
unmarshaledResult := &struct {
|
||||
Timestamp ExchangeTime `json:"ts"`
|
||||
}{}
|
||||
data5 := `{"ts":1685564775}`
|
||||
result := time.Unix(1685564775, 0)
|
||||
var err error
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err = json.Unmarshal([]byte(data5), &unmarshaledResult); err != nil {
|
||||
b.Fatal(err)
|
||||
} else if !unmarshaledResult.Timestamp.Time().Equal(result) {
|
||||
b.Fatalf("found %v, but expected %v", unmarshaledResult.Timestamp.Time(), result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2028,11 +2028,11 @@ func TestWsKlineUpdate(t *testing.T) {
|
||||
t.Parallel()
|
||||
pressXToJSON := []byte(`{"stream":"btcusdt@kline_1m","data":{
|
||||
"e": "kline",
|
||||
"E": 123456789,
|
||||
"E": 1234567891,
|
||||
"s": "BTCUSDT",
|
||||
"k": {
|
||||
"t": 123400000,
|
||||
"T": 123460000,
|
||||
"t": 1234000001,
|
||||
"T": 1234600001,
|
||||
"s": "BTCUSDT",
|
||||
"i": "1m",
|
||||
"f": 100,
|
||||
@@ -2061,14 +2061,14 @@ func TestWsTradeUpdate(t *testing.T) {
|
||||
b.SetSaveTradeDataStatus(true)
|
||||
pressXToJSON := []byte(`{"stream":"btcusdt@trade","data":{
|
||||
"e": "trade",
|
||||
"E": 123456789,
|
||||
"E": 1234567891,
|
||||
"s": "BTCUSDT",
|
||||
"t": 12345,
|
||||
"p": "0.001",
|
||||
"q": "100",
|
||||
"b": 88,
|
||||
"a": 50,
|
||||
"T": 123456785,
|
||||
"T": 1234567851,
|
||||
"m": true,
|
||||
"M": true
|
||||
}}`)
|
||||
@@ -2114,7 +2114,7 @@ func TestWsDepthUpdate(t *testing.T) {
|
||||
|
||||
update1 := []byte(`{"stream":"btcusdt@depth","data":{
|
||||
"e": "depthUpdate",
|
||||
"E": 123456788,
|
||||
"E": 1234567881,
|
||||
"s": "BTCUSDT",
|
||||
"U": 157,
|
||||
"u": 160,
|
||||
@@ -2132,7 +2132,7 @@ func TestWsDepthUpdate(t *testing.T) {
|
||||
}
|
||||
|
||||
if err := b.wsHandleData(update1); err != nil {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
b.obm.state[currency.BTC][currency.USDT][asset.Spot].fetchingBook = false
|
||||
@@ -2154,7 +2154,7 @@ func TestWsDepthUpdate(t *testing.T) {
|
||||
|
||||
update2 := []byte(`{"stream":"btcusdt@depth","data":{
|
||||
"e": "depthUpdate",
|
||||
"E": 123456789,
|
||||
"E": 1234567892,
|
||||
"s": "BTCUSDT",
|
||||
"U": 161,
|
||||
"u": 165,
|
||||
|
||||
@@ -723,18 +723,18 @@ type WithdrawResponse struct {
|
||||
|
||||
// WithdrawStatusResponse defines a withdrawal status response
|
||||
type WithdrawStatusResponse struct {
|
||||
Address string `json:"address"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
ApplyTime binanceTime `json:"applyTime"`
|
||||
Coin string `json:"coin"`
|
||||
ID string `json:"id"`
|
||||
WithdrawOrderID string `json:"withdrawOrderId"`
|
||||
Network string `json:"network"`
|
||||
TransferType uint8 `json:"transferType"`
|
||||
Status int64 `json:"status"`
|
||||
TransactionFee float64 `json:"transactionFee,string"`
|
||||
TransactionID string `json:"txId"`
|
||||
ConfirmNumber int64 `json:"confirmNo"`
|
||||
Address string `json:"address"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
ApplyTime types.Time `json:"applyTime"`
|
||||
Coin string `json:"coin"`
|
||||
ID string `json:"id"`
|
||||
WithdrawOrderID string `json:"withdrawOrderId"`
|
||||
Network string `json:"network"`
|
||||
TransferType uint8 `json:"transferType"`
|
||||
Status int64 `json:"status"`
|
||||
TransactionFee float64 `json:"transactionFee,string"`
|
||||
TransactionID string `json:"txId"`
|
||||
ConfirmNumber int64 `json:"confirmNo"`
|
||||
}
|
||||
|
||||
// DepositAddress stores the deposit address info
|
||||
@@ -921,15 +921,15 @@ type UserMarginInterestHistoryResponse struct {
|
||||
|
||||
// UserMarginInterestHistory user margin interest history row
|
||||
type UserMarginInterestHistory struct {
|
||||
TxID int64 `json:"txId"`
|
||||
InterestAccruedTime binanceTime `json:"interestAccuredTime"` // typo in docs, cannot verify due to API restrictions
|
||||
Asset string `json:"asset"`
|
||||
RawAsset string `json:"rawAsset"`
|
||||
Principal float64 `json:"principal,string"`
|
||||
Interest float64 `json:"interest,string"`
|
||||
InterestRate float64 `json:"interestRate,string"`
|
||||
Type string `json:"type"`
|
||||
IsolatedSymbol string `json:"isolatedSymbol"`
|
||||
TxID int64 `json:"txId"`
|
||||
InterestAccruedTime types.Time `json:"interestAccuredTime"` // typo in docs, cannot verify due to API restrictions
|
||||
Asset string `json:"asset"`
|
||||
RawAsset string `json:"rawAsset"`
|
||||
Principal float64 `json:"principal,string"`
|
||||
Interest float64 `json:"interest,string"`
|
||||
InterestRate float64 `json:"interestRate,string"`
|
||||
Type string `json:"type"`
|
||||
IsolatedSymbol string `json:"isolatedSymbol"`
|
||||
}
|
||||
|
||||
// CryptoLoansIncomeHistory stores crypto loan income history data
|
||||
@@ -959,7 +959,7 @@ type LoanBorrowHistoryItem struct {
|
||||
LoanTerm int64 `json:"loanTerm,string"`
|
||||
CollateralCoin currency.Code `json:"collateralCoin"`
|
||||
InitialCollateralAmount float64 `json:"initialCollateralAmount,string"`
|
||||
BorrowTime binanceTime `json:"borrowTime"`
|
||||
BorrowTime types.Time `json:"borrowTime"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
@@ -978,7 +978,7 @@ type CryptoLoanOngoingOrderItem struct {
|
||||
CollateralCoin currency.Code `json:"collateralCoin"`
|
||||
CollateralAmount float64 `json:"collateralAmount,string"`
|
||||
CurrentLTV float64 `json:"currentLTV,string"`
|
||||
ExpirationTime binanceTime `json:"expirationTime"`
|
||||
ExpirationTime types.Time `json:"expirationTime"`
|
||||
}
|
||||
|
||||
// CryptoLoanOngoingOrder stores crypto loan ongoing order data
|
||||
@@ -1006,7 +1006,7 @@ type CryptoLoanRepayHistoryItem struct {
|
||||
CollateralUsed float64 `json:"collateralUsed,string"`
|
||||
CollateralReturn float64 `json:"collateralReturn,string"`
|
||||
RepayType string `json:"repayType"`
|
||||
RepayTime binanceTime `json:"repayTime"`
|
||||
RepayTime types.Time `json:"repayTime"`
|
||||
OrderID int64 `json:"orderId"`
|
||||
}
|
||||
|
||||
@@ -1033,7 +1033,7 @@ type CryptoLoanLTVAdjustmentItem struct {
|
||||
Amount float64 `json:"amount,string"`
|
||||
PreviousLTV float64 `json:"preLTV,string"`
|
||||
AfterLTV float64 `json:"afterLTV,string"`
|
||||
AdjustTime binanceTime `json:"adjustTime"`
|
||||
AdjustTime types.Time `json:"adjustTime"`
|
||||
OrderID int64 `json:"orderId"`
|
||||
}
|
||||
|
||||
@@ -1097,7 +1097,7 @@ type CustomiseMarginCallItem struct {
|
||||
CollateralCoin currency.Code `json:"collateralCoin"`
|
||||
PreMarginCall float64 `json:"preMarginCall,string"`
|
||||
AfterMarginCall float64 `json:"afterMarginCall,string"`
|
||||
CustomiseTime binanceTime `json:"customizeTime"`
|
||||
CustomiseTime types.Time `json:"customizeTime"`
|
||||
}
|
||||
|
||||
// CustomiseMarginCall stores customise margin call data
|
||||
@@ -1136,7 +1136,7 @@ type FlexibleLoanBorrowHistoryItem struct {
|
||||
InitialLoanAmount float64 `json:"initialLoanAmount,string"`
|
||||
CollateralCoin currency.Code `json:"collateralCoin"`
|
||||
InitialCollateralAmount float64 `json:"initialCollateralAmount,string"`
|
||||
BorrowTime binanceTime `json:"borrowTime"`
|
||||
BorrowTime types.Time `json:"borrowTime"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
@@ -1164,7 +1164,7 @@ type FlexibleLoanRepayHistoryItem struct {
|
||||
CollateralCoin currency.Code `json:"collateralCoin"`
|
||||
CollateralReturn float64 `json:"collateralReturn,string"`
|
||||
RepayStatus string `json:"repayStatus"`
|
||||
RepayTime binanceTime `json:"repayTime"`
|
||||
RepayTime types.Time `json:"repayTime"`
|
||||
}
|
||||
|
||||
// FlexibleLoanRepayHistory stores flexible loan repayment history
|
||||
@@ -1191,7 +1191,7 @@ type FlexibleLoanLTVAdjustmentHistoryItem struct {
|
||||
CollateralAmount float64 `json:"collateralAmount,string"`
|
||||
PreviousLTV float64 `json:"preLTV,string"`
|
||||
AfterLTV float64 `json:"afterLTV,string"`
|
||||
AdjustTime binanceTime `json:"adjustTime"`
|
||||
AdjustTime types.Time `json:"adjustTime"`
|
||||
}
|
||||
|
||||
// FlexibleLoanLTVAdjustmentHistory stores flexible loan LTV adjustment history
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
// Response holds basic binance api response data
|
||||
@@ -15,32 +16,32 @@ type Response struct {
|
||||
|
||||
// FuturesPublicTradesData stores recent public trades for futures
|
||||
type FuturesPublicTradesData struct {
|
||||
ID int64 `json:"id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Qty float64 `json:"qty,string"`
|
||||
QuoteQty float64 `json:"quoteQty,string"`
|
||||
Time binanceTime `json:"time"`
|
||||
IsBuyerMaker bool `json:"isBuyerMaker"`
|
||||
ID int64 `json:"id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Qty float64 `json:"qty,string"`
|
||||
QuoteQty float64 `json:"quoteQty,string"`
|
||||
Time types.Time `json:"time"`
|
||||
IsBuyerMaker bool `json:"isBuyerMaker"`
|
||||
}
|
||||
|
||||
// CompressedTradesData stores futures trades data in a compressed format
|
||||
type CompressedTradesData struct {
|
||||
TradeID int64 `json:"a"`
|
||||
Price float64 `json:"p"`
|
||||
Quantity float64 `json:"q"`
|
||||
FirstTradeID int64 `json:"f"`
|
||||
LastTradeID int64 `json:"l"`
|
||||
Timestamp binanceTime `json:"t"`
|
||||
BuyerMaker bool `json:"b"`
|
||||
TradeID int64 `json:"a"`
|
||||
Price float64 `json:"p"`
|
||||
Quantity float64 `json:"q"`
|
||||
FirstTradeID int64 `json:"f"`
|
||||
LastTradeID int64 `json:"l"`
|
||||
Timestamp types.Time `json:"t"`
|
||||
BuyerMaker bool `json:"b"`
|
||||
}
|
||||
|
||||
// MarkPriceData stores mark price data for futures
|
||||
type MarkPriceData struct {
|
||||
Symbol string `json:"symbol"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
LastFundingRate float64 `json:"lastFundingRate"`
|
||||
NextFundingTime int64 `json:"nextFundingTime"`
|
||||
Time binanceTime `json:"time"`
|
||||
Symbol string `json:"symbol"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
LastFundingRate float64 `json:"lastFundingRate"`
|
||||
NextFundingTime int64 `json:"nextFundingTime"`
|
||||
Time types.Time `json:"time"`
|
||||
}
|
||||
|
||||
// SymbolPriceTicker stores ticker price stats
|
||||
@@ -445,21 +446,21 @@ type GetPositionMarginChangeHistoryData struct {
|
||||
|
||||
// FuturesPositionInformation stores futures position info
|
||||
type FuturesPositionInformation struct {
|
||||
Symbol string `json:"symbol"`
|
||||
PositionAmount float64 `json:"positionAmt,string"`
|
||||
EntryPrice float64 `json:"entryPrice,string"`
|
||||
MarkPrice float64 `json:"markPrice,string"`
|
||||
UnRealizedProfit float64 `json:"unRealizedProfit,string"`
|
||||
LiquidationPrice float64 `json:"liquidationPrice,string"`
|
||||
Leverage float64 `json:"leverage,string"`
|
||||
MaxQty float64 `json:"maxQty,string"`
|
||||
MarginType string `json:"marginType"`
|
||||
IsolatedMargin float64 `json:"isolatedMargin,string"`
|
||||
IsAutoAddMargin bool `json:"isAutoAddMargin,string"`
|
||||
PositionSide string `json:"positionSide"`
|
||||
NotionalValue float64 `json:"notionalValue,string"`
|
||||
IsolatedWallet float64 `json:"isolatedWallet,string"`
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
Symbol string `json:"symbol"`
|
||||
PositionAmount float64 `json:"positionAmt,string"`
|
||||
EntryPrice float64 `json:"entryPrice,string"`
|
||||
MarkPrice float64 `json:"markPrice,string"`
|
||||
UnRealizedProfit float64 `json:"unRealizedProfit,string"`
|
||||
LiquidationPrice float64 `json:"liquidationPrice,string"`
|
||||
Leverage float64 `json:"leverage,string"`
|
||||
MaxQty float64 `json:"maxQty,string"`
|
||||
MarginType string `json:"marginType"`
|
||||
IsolatedMargin float64 `json:"isolatedMargin,string"`
|
||||
IsAutoAddMargin bool `json:"isAutoAddMargin,string"`
|
||||
PositionSide string `json:"positionSide"`
|
||||
NotionalValue float64 `json:"notionalValue,string"`
|
||||
IsolatedWallet float64 `json:"isolatedWallet,string"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
}
|
||||
|
||||
// FuturesAccountTradeList stores account trade list data
|
||||
@@ -581,25 +582,25 @@ type UFuturesExchangeInfo struct {
|
||||
// UFuturesSymbolInfo contains details of a currency symbol
|
||||
// for a usdt margined future contract
|
||||
type UFuturesSymbolInfo struct {
|
||||
Symbol string `json:"symbol"`
|
||||
Pair string `json:"pair"`
|
||||
ContractType string `json:"contractType"`
|
||||
DeliveryDate binanceTime `json:"deliveryDate"`
|
||||
OnboardDate binanceTime `json:"onboardDate"`
|
||||
Status string `json:"status"`
|
||||
MaintenanceMarginPercent float64 `json:"maintMarginPercent,string"`
|
||||
RequiredMarginPercent float64 `json:"requiredMarginPercent,string"`
|
||||
BaseAsset string `json:"baseAsset"`
|
||||
QuoteAsset string `json:"quoteAsset"`
|
||||
MarginAsset string `json:"marginAsset"`
|
||||
PricePrecision int64 `json:"pricePrecision"`
|
||||
QuantityPrecision int64 `json:"quantityPrecision"`
|
||||
BaseAssetPrecision int64 `json:"baseAssetPrecision"`
|
||||
QuotePrecision int64 `json:"quotePrecision"`
|
||||
UnderlyingType string `json:"underlyingType"`
|
||||
UnderlyingSubType []string `json:"underlyingSubType"`
|
||||
SettlePlan float64 `json:"settlePlan"`
|
||||
TriggerProtect float64 `json:"triggerProtect,string"`
|
||||
Symbol string `json:"symbol"`
|
||||
Pair string `json:"pair"`
|
||||
ContractType string `json:"contractType"`
|
||||
DeliveryDate types.Time `json:"deliveryDate"`
|
||||
OnboardDate types.Time `json:"onboardDate"`
|
||||
Status string `json:"status"`
|
||||
MaintenanceMarginPercent float64 `json:"maintMarginPercent,string"`
|
||||
RequiredMarginPercent float64 `json:"requiredMarginPercent,string"`
|
||||
BaseAsset string `json:"baseAsset"`
|
||||
QuoteAsset string `json:"quoteAsset"`
|
||||
MarginAsset string `json:"marginAsset"`
|
||||
PricePrecision int64 `json:"pricePrecision"`
|
||||
QuantityPrecision int64 `json:"quantityPrecision"`
|
||||
BaseAssetPrecision int64 `json:"baseAssetPrecision"`
|
||||
QuotePrecision int64 `json:"quotePrecision"`
|
||||
UnderlyingType string `json:"underlyingType"`
|
||||
UnderlyingSubType []string `json:"underlyingSubType"`
|
||||
SettlePlan float64 `json:"settlePlan"`
|
||||
TriggerProtect float64 `json:"triggerProtect,string"`
|
||||
Filters []struct {
|
||||
FilterType string `json:"filterType"`
|
||||
MinPrice float64 `json:"minPrice,string"`
|
||||
@@ -644,24 +645,24 @@ type CExchangeInfo struct {
|
||||
MultiplierUp float64 `json:"multiplierUp,string"`
|
||||
MultiplierDecimal float64 `json:"multiplierDecimal,string"`
|
||||
} `json:"filters"`
|
||||
OrderTypes []string `json:"orderType"`
|
||||
TimeInForce []string `json:"timeInForce"`
|
||||
Symbol string `json:"symbol"`
|
||||
Pair string `json:"pair"`
|
||||
ContractType string `json:"contractType"`
|
||||
DeliveryDate binanceTime `json:"deliveryDate"`
|
||||
OnboardDate binanceTime `json:"onboardDate"`
|
||||
ContractStatus string `json:"contractStatus"`
|
||||
ContractSize int64 `json:"contractSize"`
|
||||
QuoteAsset string `json:"quoteAsset"`
|
||||
BaseAsset string `json:"baseAsset"`
|
||||
MarginAsset string `json:"marginAsset"`
|
||||
PricePrecision int64 `json:"pricePrecision"`
|
||||
QuantityPrecision int64 `json:"quantityPrecision"`
|
||||
BaseAssetPrecision int64 `json:"baseAssetPrecision"`
|
||||
QuotePrecision int64 `json:"quotePrecision"`
|
||||
MaintMarginPercent float64 `json:"maintMarginPercent,string"`
|
||||
RequiredMarginPercent float64 `json:"requiredMarginPercent,string"`
|
||||
OrderTypes []string `json:"orderType"`
|
||||
TimeInForce []string `json:"timeInForce"`
|
||||
Symbol string `json:"symbol"`
|
||||
Pair string `json:"pair"`
|
||||
ContractType string `json:"contractType"`
|
||||
DeliveryDate types.Time `json:"deliveryDate"`
|
||||
OnboardDate types.Time `json:"onboardDate"`
|
||||
ContractStatus string `json:"contractStatus"`
|
||||
ContractSize int64 `json:"contractSize"`
|
||||
QuoteAsset string `json:"quoteAsset"`
|
||||
BaseAsset string `json:"baseAsset"`
|
||||
MarginAsset string `json:"marginAsset"`
|
||||
PricePrecision int64 `json:"pricePrecision"`
|
||||
QuantityPrecision int64 `json:"quantityPrecision"`
|
||||
BaseAssetPrecision int64 `json:"baseAssetPrecision"`
|
||||
QuotePrecision int64 `json:"quotePrecision"`
|
||||
MaintMarginPercent float64 `json:"maintMarginPercent,string"`
|
||||
RequiredMarginPercent float64 `json:"requiredMarginPercent,string"`
|
||||
} `json:"symbols"`
|
||||
Timezone string `json:"timezone"`
|
||||
}
|
||||
|
||||
@@ -2,40 +2,12 @@ package binance
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
// binanceTime provides an internal conversion helper
|
||||
type binanceTime time.Time
|
||||
|
||||
func (t *binanceTime) UnmarshalJSON(data []byte) error {
|
||||
var result interface{}
|
||||
if err := json.Unmarshal(data, &result); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch v := result.(type) {
|
||||
case string:
|
||||
timestamp, err := strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = binanceTime(time.UnixMilli(timestamp))
|
||||
case float64:
|
||||
*t = binanceTime(time.UnixMilli(int64(v)))
|
||||
default:
|
||||
return errors.New("invalid time format received")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Time returns a time.Time object
|
||||
func (t binanceTime) Time() time.Time {
|
||||
return time.Time(t)
|
||||
}
|
||||
|
||||
// timeString gets the time as Binance timestamp
|
||||
func timeString(t time.Time) string {
|
||||
return strconv.FormatInt(t.UnixMilli(), 10)
|
||||
@@ -45,7 +17,7 @@ func timeString(t time.Time) string {
|
||||
func (a *ExchangeInfo) UnmarshalJSON(data []byte) error {
|
||||
type Alias ExchangeInfo
|
||||
aux := &struct {
|
||||
Servertime binanceTime `json:"serverTime"`
|
||||
Servertime types.Time `json:"serverTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -61,7 +33,7 @@ func (a *ExchangeInfo) UnmarshalJSON(data []byte) error {
|
||||
func (a *AggregatedTrade) UnmarshalJSON(data []byte) error {
|
||||
type Alias AggregatedTrade
|
||||
aux := &struct {
|
||||
TimeStamp binanceTime `json:"T"`
|
||||
TimeStamp types.Time `json:"T"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -77,7 +49,7 @@ func (a *AggregatedTrade) UnmarshalJSON(data []byte) error {
|
||||
func (a *NewOrderResponse) UnmarshalJSON(data []byte) error {
|
||||
type Alias NewOrderResponse
|
||||
aux := &struct {
|
||||
TransactionTime binanceTime `json:"transactTime"`
|
||||
TransactionTime types.Time `json:"transactTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -95,8 +67,8 @@ func (a *NewOrderResponse) UnmarshalJSON(data []byte) error {
|
||||
func (a *TradeStream) UnmarshalJSON(data []byte) error {
|
||||
type Alias TradeStream
|
||||
aux := &struct {
|
||||
TimeStamp binanceTime `json:"T"`
|
||||
EventTime binanceTime `json:"E"`
|
||||
TimeStamp types.Time `json:"T"`
|
||||
EventTime types.Time `json:"E"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -113,10 +85,10 @@ func (a *TradeStream) UnmarshalJSON(data []byte) error {
|
||||
func (a *KlineStream) UnmarshalJSON(data []byte) error {
|
||||
type Alias KlineStream
|
||||
aux := &struct {
|
||||
EventTime binanceTime `json:"E"`
|
||||
EventTime types.Time `json:"E"`
|
||||
Kline struct {
|
||||
StartTime binanceTime `json:"t"`
|
||||
CloseTime binanceTime `json:"T"`
|
||||
StartTime types.Time `json:"t"`
|
||||
CloseTime types.Time `json:"T"`
|
||||
*KlineStreamData
|
||||
} `json:"k"`
|
||||
*Alias
|
||||
@@ -137,9 +109,9 @@ func (a *KlineStream) UnmarshalJSON(data []byte) error {
|
||||
func (a *TickerStream) UnmarshalJSON(data []byte) error {
|
||||
type Alias TickerStream
|
||||
aux := &struct {
|
||||
EventTime binanceTime `json:"E"`
|
||||
OpenTime binanceTime `json:"O"`
|
||||
CloseTime binanceTime `json:"C"`
|
||||
EventTime types.Time `json:"E"`
|
||||
OpenTime types.Time `json:"O"`
|
||||
CloseTime types.Time `json:"C"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -157,8 +129,8 @@ func (a *TickerStream) UnmarshalJSON(data []byte) error {
|
||||
func (a *PriceChangeStats) UnmarshalJSON(data []byte) error {
|
||||
type Alias PriceChangeStats
|
||||
aux := &struct {
|
||||
OpenTime binanceTime `json:"openTime"`
|
||||
CloseTime binanceTime `json:"closeTime"`
|
||||
OpenTime types.Time `json:"openTime"`
|
||||
CloseTime types.Time `json:"closeTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -175,7 +147,7 @@ func (a *PriceChangeStats) UnmarshalJSON(data []byte) error {
|
||||
func (a *RecentTrade) UnmarshalJSON(data []byte) error {
|
||||
type Alias RecentTrade
|
||||
aux := &struct {
|
||||
Time binanceTime `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -191,7 +163,7 @@ func (a *RecentTrade) UnmarshalJSON(data []byte) error {
|
||||
func (a *HistoricalTrade) UnmarshalJSON(data []byte) error {
|
||||
type Alias HistoricalTrade
|
||||
aux := &struct {
|
||||
Time binanceTime `json:"time"`
|
||||
Time types.Time `json:"time"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -207,8 +179,8 @@ func (a *HistoricalTrade) UnmarshalJSON(data []byte) error {
|
||||
func (a *QueryOrderData) UnmarshalJSON(data []byte) error {
|
||||
type Alias QueryOrderData
|
||||
aux := &struct {
|
||||
Time binanceTime `json:"time"`
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
Time types.Time `json:"time"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -225,8 +197,8 @@ func (a *QueryOrderData) UnmarshalJSON(data []byte) error {
|
||||
func (a *FuturesOrderData) UnmarshalJSON(data []byte) error {
|
||||
type Alias FuturesOrderData
|
||||
aux := &struct {
|
||||
Time binanceTime `json:"time"`
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
Time types.Time `json:"time"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -243,8 +215,8 @@ func (a *FuturesOrderData) UnmarshalJSON(data []byte) error {
|
||||
func (a *UFuturesOrderData) UnmarshalJSON(data []byte) error {
|
||||
type Alias UFuturesOrderData
|
||||
aux := &struct {
|
||||
Time binanceTime `json:"time"`
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
Time types.Time `json:"time"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -261,8 +233,8 @@ func (a *UFuturesOrderData) UnmarshalJSON(data []byte) error {
|
||||
func (a *FuturesOrderGetData) UnmarshalJSON(data []byte) error {
|
||||
type Alias FuturesOrderGetData
|
||||
aux := &struct {
|
||||
Time binanceTime `json:"time"`
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
Time types.Time `json:"time"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -279,8 +251,8 @@ func (a *FuturesOrderGetData) UnmarshalJSON(data []byte) error {
|
||||
func (a *UOrderData) UnmarshalJSON(data []byte) error {
|
||||
type Alias UOrderData
|
||||
aux := &struct {
|
||||
Time binanceTime `json:"time"`
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
Time types.Time `json:"time"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -297,7 +269,7 @@ func (a *UOrderData) UnmarshalJSON(data []byte) error {
|
||||
func (a *Account) UnmarshalJSON(data []byte) error {
|
||||
type Alias Account
|
||||
aux := &struct {
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -313,7 +285,7 @@ func (a *Account) UnmarshalJSON(data []byte) error {
|
||||
func (a *WebsocketDepthStream) UnmarshalJSON(data []byte) error {
|
||||
type Alias WebsocketDepthStream
|
||||
aux := &struct {
|
||||
Timestamp binanceTime `json:"E"`
|
||||
Timestamp types.Time `json:"E"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -330,8 +302,8 @@ func (a *wsAccountPosition) UnmarshalJSON(data []byte) error {
|
||||
type Alias wsAccountPosition
|
||||
aux := &struct {
|
||||
Data struct {
|
||||
EventTime binanceTime `json:"E"`
|
||||
LastUpdated binanceTime `json:"u"`
|
||||
EventTime types.Time `json:"E"`
|
||||
LastUpdated types.Time `json:"u"`
|
||||
*WsAccountPositionData
|
||||
} `json:"data"`
|
||||
*Alias
|
||||
@@ -352,8 +324,8 @@ func (a *wsBalanceUpdate) UnmarshalJSON(data []byte) error {
|
||||
type Alias wsBalanceUpdate
|
||||
aux := &struct {
|
||||
Data struct {
|
||||
EventTime binanceTime `json:"E"`
|
||||
ClearTime binanceTime `json:"T"`
|
||||
EventTime types.Time `json:"E"`
|
||||
ClearTime types.Time `json:"T"`
|
||||
*WsBalanceUpdateData
|
||||
} `json:"data"`
|
||||
*Alias
|
||||
@@ -374,10 +346,10 @@ func (a *wsOrderUpdate) UnmarshalJSON(data []byte) error {
|
||||
type Alias wsOrderUpdate
|
||||
aux := &struct {
|
||||
Data struct {
|
||||
EventTime binanceTime `json:"E"`
|
||||
OrderCreationTime binanceTime `json:"O"`
|
||||
TransactionTime binanceTime `json:"T"`
|
||||
WorkingTime binanceTime `json:"W"`
|
||||
EventTime types.Time `json:"E"`
|
||||
OrderCreationTime types.Time `json:"O"`
|
||||
TransactionTime types.Time `json:"T"`
|
||||
WorkingTime types.Time `json:"W"`
|
||||
*WsOrderUpdateData
|
||||
} `json:"data"`
|
||||
*Alias
|
||||
@@ -400,8 +372,8 @@ func (a *wsListStatus) UnmarshalJSON(data []byte) error {
|
||||
type Alias wsListStatus
|
||||
aux := &struct {
|
||||
Data struct {
|
||||
EventTime binanceTime `json:"E"`
|
||||
TransactionTime binanceTime `json:"T"`
|
||||
EventTime types.Time `json:"E"`
|
||||
TransactionTime types.Time `json:"T"`
|
||||
*WsListStatusData
|
||||
} `json:"data"`
|
||||
*Alias
|
||||
@@ -422,7 +394,7 @@ func (a *FuturesAccountInformationPosition) UnmarshalJSON(data []byte) error {
|
||||
type Alias FuturesAccountInformationPosition
|
||||
|
||||
aux := &struct {
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -442,7 +414,7 @@ func (a *FuturesAccountInformation) UnmarshalJSON(data []byte) error {
|
||||
type Alias FuturesAccountInformation
|
||||
|
||||
aux := &struct {
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
|
||||
@@ -52,12 +52,12 @@ type OrderbookData struct {
|
||||
|
||||
// UPublicTradesData stores trade data
|
||||
type UPublicTradesData struct {
|
||||
ID int64 `json:"id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Qty float64 `json:"qty,string"`
|
||||
QuoteQty float64 `json:"quoteQty,string"`
|
||||
Time binanceTime `json:"time"`
|
||||
IsBuyerMaker bool `json:"isBuyerMaker"`
|
||||
ID int64 `json:"id"`
|
||||
Price float64 `json:"price,string"`
|
||||
Qty float64 `json:"qty,string"`
|
||||
QuoteQty float64 `json:"quoteQty,string"`
|
||||
Time types.Time `json:"time"`
|
||||
IsBuyerMaker bool `json:"isBuyerMaker"`
|
||||
}
|
||||
|
||||
// UCompressedTradeData stores compressed trade data
|
||||
@@ -300,22 +300,22 @@ type UAsset struct {
|
||||
|
||||
// UPosition holds account position information
|
||||
type UPosition struct {
|
||||
Symbol string `json:"symbol"`
|
||||
InitialMargin float64 `json:"initialMargin,string"`
|
||||
MaintenanceMargin float64 `json:"maintMargin,string"`
|
||||
UnrealisedProfit float64 `json:"unrealizedProfit,string"`
|
||||
PositionInitialMargin float64 `json:"positionInitialMargin,string"`
|
||||
OpenOrderInitialMargin float64 `json:"openOrderInitialMargin,string"`
|
||||
Leverage float64 `json:"leverage,string"`
|
||||
Isolated bool `json:"isolated"`
|
||||
IsolatedWallet float64 `json:"isolatedWallet,string"`
|
||||
EntryPrice float64 `json:"entryPrice,string"`
|
||||
MaxNotional float64 `json:"maxNotional,string"`
|
||||
BidNotional float64 `json:"bidNotional,string"`
|
||||
AskNotional float64 `json:"askNotional,string"`
|
||||
PositionSide string `json:"positionSide"`
|
||||
PositionAmount float64 `json:"positionAmt,string"`
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
Symbol string `json:"symbol"`
|
||||
InitialMargin float64 `json:"initialMargin,string"`
|
||||
MaintenanceMargin float64 `json:"maintMargin,string"`
|
||||
UnrealisedProfit float64 `json:"unrealizedProfit,string"`
|
||||
PositionInitialMargin float64 `json:"positionInitialMargin,string"`
|
||||
OpenOrderInitialMargin float64 `json:"openOrderInitialMargin,string"`
|
||||
Leverage float64 `json:"leverage,string"`
|
||||
Isolated bool `json:"isolated"`
|
||||
IsolatedWallet float64 `json:"isolatedWallet,string"`
|
||||
EntryPrice float64 `json:"entryPrice,string"`
|
||||
MaxNotional float64 `json:"maxNotional,string"`
|
||||
BidNotional float64 `json:"bidNotional,string"`
|
||||
AskNotional float64 `json:"askNotional,string"`
|
||||
PositionSide string `json:"positionSide"`
|
||||
PositionAmount float64 `json:"positionAmt,string"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
}
|
||||
|
||||
// UChangeInitialLeverage stores leverage change data
|
||||
@@ -343,21 +343,21 @@ type UPositionMarginChangeHistoryData struct {
|
||||
|
||||
// UPositionInformationV2 stores positions data
|
||||
type UPositionInformationV2 struct {
|
||||
Symbol string `json:"symbol"`
|
||||
PositionAmount float64 `json:"positionAmt,string"`
|
||||
EntryPrice float64 `json:"entryPrice,string"`
|
||||
MarkPrice float64 `json:"markPrice,string"`
|
||||
UnrealizedProfit float64 `json:"unrealizedProfit,string"`
|
||||
LiquidationPrice float64 `json:"liquidationPrice,string"`
|
||||
Leverage float64 `json:"leverage,string"`
|
||||
MaxNotionalValue float64 `json:"maxNotionalValue,string"`
|
||||
MarginType string `json:"marginType"`
|
||||
IsAutoAddMargin bool `json:"isAutoAddMargin,string"`
|
||||
PositionSide string `json:"positionSide"`
|
||||
Notional float64 `json:"notional,string"`
|
||||
IsolatedWallet float64 `json:"isolatedWallet,string"`
|
||||
IsolatedMargin float64 `json:"isolatedMargin,string"`
|
||||
UpdateTime binanceTime `json:"updateTime"`
|
||||
Symbol string `json:"symbol"`
|
||||
PositionAmount float64 `json:"positionAmt,string"`
|
||||
EntryPrice float64 `json:"entryPrice,string"`
|
||||
MarkPrice float64 `json:"markPrice,string"`
|
||||
UnrealizedProfit float64 `json:"unrealizedProfit,string"`
|
||||
LiquidationPrice float64 `json:"liquidationPrice,string"`
|
||||
Leverage float64 `json:"leverage,string"`
|
||||
MaxNotionalValue float64 `json:"maxNotionalValue,string"`
|
||||
MarginType string `json:"marginType"`
|
||||
IsAutoAddMargin bool `json:"isAutoAddMargin,string"`
|
||||
PositionSide string `json:"positionSide"`
|
||||
Notional float64 `json:"notional,string"`
|
||||
IsolatedWallet float64 `json:"isolatedWallet,string"`
|
||||
IsolatedMargin float64 `json:"isolatedMargin,string"`
|
||||
UpdateTime types.Time `json:"updateTime"`
|
||||
}
|
||||
|
||||
// UAccountTradeHistory stores trade data for the users account
|
||||
|
||||
@@ -1307,7 +1307,7 @@ var ticker24hourChangeStream = `{
|
||||
"stream":"btcusdt@ticker",
|
||||
"data" :{
|
||||
"e": "24hrTicker",
|
||||
"E": 123456789,
|
||||
"E": 1234567891,
|
||||
"s": "BNBBTC",
|
||||
"p": "0.0015",
|
||||
"P": "250.00",
|
||||
@@ -1325,7 +1325,7 @@ var ticker24hourChangeStream = `{
|
||||
"v": "10000",
|
||||
"q": "18",
|
||||
"O": 0,
|
||||
"C": 86400000,
|
||||
"C": 8640000011,
|
||||
"F": 0,
|
||||
"L": 18150,
|
||||
"n": 18151
|
||||
@@ -1346,11 +1346,11 @@ func TestWebsocketKlineUpdate(t *testing.T) {
|
||||
"stream":"btcusdt@kline_1m",
|
||||
"data":{
|
||||
"e": "kline",
|
||||
"E": 123456789,
|
||||
"E": 1234567891,
|
||||
"s": "BNBBTC",
|
||||
"k": {
|
||||
"t": 123400000,
|
||||
"T": 123460000,
|
||||
"t": 1234000001,
|
||||
"T": 1234600001,
|
||||
"s": "BNBBTC",
|
||||
"i": "1m",
|
||||
"f": 100,
|
||||
@@ -1429,7 +1429,7 @@ func TestWebsocketOrderBookDepthDiffStream(t *testing.T) {
|
||||
}
|
||||
update1 := []byte(`{"stream":"btcusdt@depth","data":{
|
||||
"e": "depthUpdate",
|
||||
"E": 123456788,
|
||||
"E": 1234567891,
|
||||
"s": "BTCUSDT",
|
||||
"U": 157,
|
||||
"u": 160,
|
||||
@@ -1446,7 +1446,7 @@ func TestWebsocketOrderBookDepthDiffStream(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := bi.wsHandleData(update1); err != nil {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
bi.obm.state[currency.BTC][currency.USDT][asset.Spot].fetchingBook = false
|
||||
ob, err := bi.Websocket.Orderbook.GetOrderbook(p, asset.Spot)
|
||||
@@ -1465,7 +1465,7 @@ func TestWebsocketOrderBookDepthDiffStream(t *testing.T) {
|
||||
update2 := []byte(`{
|
||||
"stream":"btcusdt@depth","data":{
|
||||
"e": "depthUpdate",
|
||||
"E": 123456789,
|
||||
"E": 1234567892,
|
||||
"s": "BTCUSDT",
|
||||
"U": 161,
|
||||
"u": 165,
|
||||
@@ -1686,7 +1686,7 @@ func TestExecutionTypeToOrderStatus(t *testing.T) {
|
||||
var websocketDepthUpdate = []byte(
|
||||
`{
|
||||
"e": "depthUpdate",
|
||||
"E": 123456789,
|
||||
"E": 12345678911,
|
||||
"s": "BNBBTC",
|
||||
"U": 157,
|
||||
"u": 160,
|
||||
|
||||
@@ -3,6 +3,8 @@ package binanceus
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
// UnmarshalJSON deserialises the JSON info, including the timestamp
|
||||
@@ -139,7 +141,7 @@ func (a *Account) UnmarshalJSON(data []byte) error {
|
||||
func (a *NewOrderResponse) UnmarshalJSON(data []byte) error {
|
||||
type Alias NewOrderResponse
|
||||
aux := &struct {
|
||||
TransactionTime binanceusTime `json:"transactTime"`
|
||||
TransactionTime types.Time `json:"transactTime"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -306,8 +308,8 @@ func (a *WsListStatus) UnmarshalJSON(data []byte) error {
|
||||
type Alias WsListStatus
|
||||
aux := &struct {
|
||||
Data struct {
|
||||
EventTime binanceusTime `json:"E"`
|
||||
TransactionTime binanceusTime `json:"T"`
|
||||
EventTime types.Time `json:"E"`
|
||||
TransactionTime types.Time `json:"T"`
|
||||
*WsListStatusData
|
||||
} `json:"data"`
|
||||
*Alias
|
||||
@@ -327,9 +329,9 @@ func (a *WsListStatus) UnmarshalJSON(data []byte) error {
|
||||
func (a *TickerStream) UnmarshalJSON(data []byte) error {
|
||||
type Alias TickerStream
|
||||
aux := &struct {
|
||||
EventTime binanceusTime `json:"E"`
|
||||
OpenTime binanceusTime `json:"O"`
|
||||
CloseTime binanceusTime `json:"C"`
|
||||
EventTime types.Time `json:"E"`
|
||||
OpenTime types.Time `json:"O"`
|
||||
CloseTime types.Time `json:"C"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -347,10 +349,10 @@ func (a *TickerStream) UnmarshalJSON(data []byte) error {
|
||||
func (a *KlineStream) UnmarshalJSON(data []byte) error {
|
||||
type Alias KlineStream
|
||||
aux := &struct {
|
||||
EventTime binanceusTime `json:"E"`
|
||||
EventTime types.Time `json:"E"`
|
||||
Kline struct {
|
||||
StartTime binanceusTime `json:"t"`
|
||||
CloseTime binanceusTime `json:"T"`
|
||||
StartTime types.Time `json:"t"`
|
||||
CloseTime types.Time `json:"T"`
|
||||
*KlineStreamData
|
||||
} `json:"k"`
|
||||
*Alias
|
||||
@@ -371,8 +373,8 @@ func (a *KlineStream) UnmarshalJSON(data []byte) error {
|
||||
func (a *TradeStream) UnmarshalJSON(data []byte) error {
|
||||
type Alias TradeStream
|
||||
aux := &struct {
|
||||
TimeStamp binanceusTime `json:"T"`
|
||||
EventTime binanceusTime `json:"E"`
|
||||
TimeStamp types.Time `json:"T"`
|
||||
EventTime types.Time `json:"E"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -390,9 +392,9 @@ func (a *wsOrderUpdate) UnmarshalJSON(data []byte) error {
|
||||
type Alias wsOrderUpdate
|
||||
aux := &struct {
|
||||
Data struct {
|
||||
EventTime binanceusTime `json:"E"`
|
||||
OrderCreationTime binanceusTime `json:"O"`
|
||||
TransactionTime binanceusTime `json:"T"`
|
||||
EventTime types.Time `json:"E"`
|
||||
OrderCreationTime types.Time `json:"O"`
|
||||
TransactionTime types.Time `json:"T"`
|
||||
*WsOrderUpdateData
|
||||
} `json:"data"`
|
||||
*Alias
|
||||
@@ -414,8 +416,8 @@ func (a *wsBalanceUpdate) UnmarshalJSON(data []byte) error {
|
||||
type Alias wsBalanceUpdate
|
||||
aux := &struct {
|
||||
Data struct {
|
||||
EventTime binanceusTime `json:"E"`
|
||||
ClearTime binanceusTime `json:"T"`
|
||||
EventTime types.Time `json:"E"`
|
||||
ClearTime types.Time `json:"T"`
|
||||
*WsBalanceUpdateData
|
||||
} `json:"data"`
|
||||
*Alias
|
||||
@@ -436,8 +438,8 @@ func (a *wsAccountPosition) UnmarshalJSON(data []byte) error {
|
||||
type Alias wsAccountPosition
|
||||
aux := &struct {
|
||||
Data struct {
|
||||
EventTime binanceusTime `json:"E"`
|
||||
LastUpdated binanceusTime `json:"u"`
|
||||
EventTime types.Time `json:"E"`
|
||||
LastUpdated types.Time `json:"u"`
|
||||
*WsAccountPositionData
|
||||
} `json:"data"`
|
||||
*Alias
|
||||
@@ -457,7 +459,7 @@ func (a *wsAccountPosition) UnmarshalJSON(data []byte) error {
|
||||
func (a *WebsocketDepthStream) UnmarshalJSON(data []byte) error {
|
||||
type Alias WebsocketDepthStream
|
||||
aux := &struct {
|
||||
Timestamp binanceusTime `json:"E"`
|
||||
Timestamp types.Time `json:"E"`
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(a),
|
||||
@@ -491,23 +493,6 @@ func (a *WebsocketAggregateTradeStream) UnmarshalJSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// binanceTime provides an internal conversion helper
|
||||
type binanceusTime time.Time
|
||||
|
||||
func (t *binanceusTime) UnmarshalJSON(data []byte) error {
|
||||
var timestamp int64
|
||||
if err := json.Unmarshal(data, ×tamp); err != nil {
|
||||
return err
|
||||
}
|
||||
*t = binanceusTime(time.UnixMilli(timestamp))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Time returns a time.Time object
|
||||
func (t binanceusTime) Time() time.Time {
|
||||
return time.Time(t)
|
||||
}
|
||||
|
||||
// UnmarshalJSON deserialises createTime timestamp to built in time.
|
||||
func (a *OCBSOrder) UnmarshalJSON(data []byte) error {
|
||||
type Alias OCBSOrder
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
// Ticker holds ticker data
|
||||
@@ -127,17 +128,17 @@ type Orders struct {
|
||||
|
||||
// OrderData contains all individual order details
|
||||
type OrderData struct {
|
||||
OrderID string `json:"order_id"`
|
||||
OrderCurrency string `json:"order_currency"`
|
||||
OrderDate bithumbTime `json:"order_date"`
|
||||
PaymentCurrency string `json:"payment_currency"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Units float64 `json:"units,string"`
|
||||
UnitsRemaining float64 `json:"units_remaining,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Total float64 `json:"total,string"`
|
||||
OrderID string `json:"order_id"`
|
||||
OrderCurrency string `json:"order_currency"`
|
||||
OrderDate types.Time `json:"order_date"`
|
||||
PaymentCurrency string `json:"payment_currency"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Units float64 `json:"units,string"`
|
||||
UnitsRemaining float64 `json:"units_remaining,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Total float64 `json:"total,string"`
|
||||
}
|
||||
|
||||
// UserTransactions holds users full transaction list
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
// WsResponse is a generalised response data structure which will defer
|
||||
@@ -41,7 +42,7 @@ type WsTicker struct {
|
||||
// WsOrderbooks defines an amalgamated bid ask orderbook tranche list
|
||||
type WsOrderbooks struct {
|
||||
List []WsOrderbook `json:"list"`
|
||||
DateTime bithumbTime `json:"datetime"`
|
||||
DateTime types.Time `json:"datetime"`
|
||||
}
|
||||
|
||||
// WsOrderbook defines a singular orderbook tranche
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package bithumb
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// bithumbMSTime provides an internal conversion helper for microsecond parsing
|
||||
type bithumbTime time.Time
|
||||
|
||||
// UnmarshalJSON implements the unmarshal interface
|
||||
func (t *bithumbTime) UnmarshalJSON(data []byte) error {
|
||||
var timestamp string
|
||||
if err := json.Unmarshal(data, ×tamp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i, err := strconv.ParseInt(timestamp, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = bithumbTime(time.Unix(0, i*int64(time.Microsecond)))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Time returns a time.Time object
|
||||
func (t bithumbTime) Time() time.Time {
|
||||
return time.Time(t)
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package bithumb
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBithumbTime(t *testing.T) {
|
||||
var newTime bithumbTime
|
||||
err := json.Unmarshal([]byte("bad news"), &newTime)
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
strData := []byte(`"1628739590000000"`) // Thursday, August 12, 2021 3:39:50 AM UTC
|
||||
err = json.Unmarshal(strData, &newTime)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tt := newTime.Time()
|
||||
if tt.UTC().String() != "2021-08-12 03:39:50 +0000 UTC" {
|
||||
t.Fatalf("expected: %s but received: %s",
|
||||
"2021-08-12 03:39:50 +0000 UTC",
|
||||
tt.UTC().String())
|
||||
}
|
||||
}
|
||||
@@ -5,69 +5,10 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
)
|
||||
|
||||
// datetime provides an internal conversion helper
|
||||
type datetime time.Time
|
||||
|
||||
func (d *datetime) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t, err := convert.UnixTimestampStrToTime(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*d = datetime(t)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Time returns datetime cast directly as time.Time
|
||||
func (d datetime) Time() time.Time {
|
||||
return time.Time(d)
|
||||
}
|
||||
|
||||
// microTimestamp provides an internal conversion helper
|
||||
type microTimestamp time.Time
|
||||
|
||||
func (t *microTimestamp) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if strconv.IntSize == 32 && len(s) >= 10 {
|
||||
i, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = microTimestamp(time.UnixMicro(i))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Has Fast path optimisation when int == 64
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = microTimestamp(time.UnixMicro(int64(i)))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Time returns datetime cast directly as time.Time
|
||||
func (t microTimestamp) Time() time.Time {
|
||||
return time.Time(t)
|
||||
}
|
||||
|
||||
// UnmarshalJSON deserializes JSON, and timestamp information.
|
||||
func (p *TradingPair) UnmarshalJSON(data []byte) error {
|
||||
type Alias TradingPair
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
// Transaction types
|
||||
@@ -283,14 +284,14 @@ type websocketOrderResponse struct {
|
||||
}
|
||||
|
||||
type websocketOrderData struct {
|
||||
ID int64 `json:"id"`
|
||||
IDStr string `json:"id_str"`
|
||||
ClientOrderID string `json:"client_order_id"`
|
||||
RemainingAmount float64 `json:"amount"`
|
||||
ExecutedAmount float64 `json:"amount_traded,string"` // Not Cumulative; Partial fill amount
|
||||
Amount float64 `json:"amount_at_create,string"`
|
||||
Price float64 `json:"price"`
|
||||
Side orderSide `json:"order_type"`
|
||||
Datetime datetime `json:"datetime"`
|
||||
Microtimestamp microTimestamp `json:"microtimestamp"`
|
||||
ID int64 `json:"id"`
|
||||
IDStr string `json:"id_str"`
|
||||
ClientOrderID string `json:"client_order_id"`
|
||||
RemainingAmount float64 `json:"amount"`
|
||||
ExecutedAmount float64 `json:"amount_traded,string"` // Not Cumulative; Partial fill amount
|
||||
Amount float64 `json:"amount_at_create,string"`
|
||||
Price float64 `json:"price"`
|
||||
Side orderSide `json:"order_type"`
|
||||
Datetime types.Time `json:"datetime"`
|
||||
Microtimestamp types.Time `json:"microtimestamp"`
|
||||
}
|
||||
|
||||
@@ -3226,7 +3226,7 @@ func TestWsTicker(t *testing.T) {
|
||||
assert.Equal(t, 6780.866843, v.Volume, "Volume should be correct")
|
||||
assert.Equal(t, "BTC_USDT", v.Pair.String(), "Pair should be correct")
|
||||
assert.Equal(t, asset.Spot, v.AssetType, "AssetType should be correct")
|
||||
assert.Equal(t, int64(233366401000), v.LastUpdated.UnixMilli(), "LastUpdated should be correct")
|
||||
assert.Equal(t, int64(1715742949283), v.LastUpdated.UnixMilli(), "LastUpdated should be correct")
|
||||
case 2: // Option
|
||||
assert.Equal(t, currency.BTC, v.Pair.Base, "Pair base should be correct")
|
||||
assert.Equal(t, 3565.00, v.Last, "Last should be correct")
|
||||
@@ -3306,7 +3306,7 @@ func TestWsTicker(t *testing.T) {
|
||||
assert.Equal(t, 61942.85, v.IndexPrice, "IndexPrice should be correct")
|
||||
assert.Equal(t, 526.806, v.OpenInterest, "OpenInterest should be correct")
|
||||
assert.Equal(t, asset.USDCMarginedFutures, v.AssetType, "AssetType should be correct")
|
||||
assert.Equal(t, int64(171575661221), v.LastUpdated.UnixMilli(), "LastUpdated should be correct")
|
||||
assert.Equal(t, int64(1715756612210), v.LastUpdated.UnixMilli(), "LastUpdated should be correct")
|
||||
case 7: // CoinMargined snapshot
|
||||
assert.Equal(t, currency.BTC, v.Pair.Base, "Pair base should be correct")
|
||||
assert.Equal(t, currency.USD, v.Pair.Quote, "Pair quote should be correct")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2
exchanges/bybit/testdata/wsTicker.json
vendored
2
exchanges/bybit/testdata/wsTicker.json
vendored
@@ -1,4 +1,4 @@
|
||||
{"topic":"tickers.BTC-USDT","type":"snapshot","ts":233366401000,"cs":2588407389,"data":{"symbol":"BTCUSDT","lastPrice":"21109.77","highPrice24h":"21426.99","lowPrice24h":"20575","prevPrice24h":"20704.93","volume24h":"6780.866843","turnover24h":"141946527.22907118","price24hPcnt":"0.0196","usdIndexPrice":"21120.2400136"}}
|
||||
{"topic":"tickers.BTC-USDT","type":"snapshot","ts":1715742949283,"cs":2588407389,"data":{"symbol":"BTCUSDT","lastPrice":"21109.77","highPrice24h":"21426.99","lowPrice24h":"20575","prevPrice24h":"20704.93","volume24h":"6780.866843","turnover24h":"141946527.22907118","price24hPcnt":"0.0196","usdIndexPrice":"21120.2400136"}}
|
||||
{"topic":"tickers.BTC-28JUN24-60000-P","ts":1715742949283,"type":"snapshot","id":"tickers.BTC-28JUN24-60000-P-6222585724-1715742949283","data":{"symbol":"BTC-28JUN24-60000-P","bidPrice":"3475","bidSize":"10.14","bidIv":"0.5479","askPrice":"3520","askSize":"2.5","askIv":"0.5534","lastPrice":"3565","highPrice24h":"3715","lowPrice24h":"3555","markPrice":"3502.0715721","indexPrice":"61912.8","markPriceIv":"0.5513","underlyingPrice":"62588.50709846","openInterest":"29.35","turnover24h":"101005.6875725","volume24h":"1.62","totalVolume":"45","totalTurnover":"2911557","delta":"-0.37596534","gamma":"0.00003161","vega":"82.65324199","theta":"-51.54651685","predictedDeliveryPrice":"0","change24h":"0.02148998"}}
|
||||
{"topic":"tickers.BTCUSDT","type":"snapshot","data":{"symbol":"BTCUSDT","tickDirection":"ZeroPlusTick","price24hPcnt":"-0.009772","lastPrice":"61874.00","prevPrice24h":"62484.60","highPrice24h":"62752.90","lowPrice24h":"61000.10","prevPrice1h":"61901.80","markPrice":"61875.25","indexPrice":"61903.73","openInterest":"58117.022","openInterestValue":"3596005265.51","turnover24h":"6073739017.8331","volume24h":"98430.1050","nextFundingTime":"1715760000000","fundingRate":"0.00008055","bid1Price":"61873.90","bid1Size":"3.783","ask1Price":"61874.00","ask1Size":"16.278"},"cs":176530003895,"ts":1715748762463}
|
||||
{"topic":"tickers.BTCUSDT","type":"delta","data":{"symbol":"BTCUSDT","markPrice":"61875.06","indexPrice":"61903.59","openInterestValue":"3595994223.27","bid1Price":"61873.90","bid1Size":"3.543"},"cs":176530004279,"ts":1715748763063}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,72 +0,0 @@
|
||||
package gateio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
zero = []byte(`0`)
|
||||
emptyStr = []byte(`""`)
|
||||
zeroStr = []byte(`"0"`)
|
||||
)
|
||||
|
||||
// Time represents a time.Time object that can be unmarshalled from a float64 or string.
|
||||
type Time time.Time
|
||||
|
||||
// UnmarshalJSON deserializes json, and timestamp information.
|
||||
func (a *Time) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, zero) || bytes.Equal(data, emptyStr) || bytes.Equal(data, zeroStr) {
|
||||
*a = Time(time.Time{})
|
||||
return nil
|
||||
}
|
||||
|
||||
s := string(data)
|
||||
if s[0] == '"' {
|
||||
s = s[1 : len(s)-1]
|
||||
}
|
||||
|
||||
target := strings.Index(s, ".")
|
||||
if target != -1 {
|
||||
s = s[:target] + s[target+1:]
|
||||
}
|
||||
|
||||
standard, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch len(s) {
|
||||
case 10:
|
||||
// Seconds
|
||||
*a = Time(time.Unix(standard, 0))
|
||||
case 11, 12:
|
||||
// Milliseconds: 1726104395.5 && 1726104395.56
|
||||
*a = Time(time.UnixMilli(standard * int64(math.Pow10(13-len(s)))))
|
||||
case 13:
|
||||
// Milliseconds
|
||||
*a = Time(time.UnixMilli(standard))
|
||||
case 14:
|
||||
// MicroSeconds: 1726106210903.0
|
||||
*a = Time(time.UnixMicro(standard * 100))
|
||||
case 16:
|
||||
// MicroSeconds
|
||||
*a = Time(time.UnixMicro(standard))
|
||||
case 17:
|
||||
// NanoSeconds: 1606292218213.4578
|
||||
*a = Time(time.Unix(0, standard*100))
|
||||
case 19:
|
||||
// NanoSeconds
|
||||
*a = Time(time.Unix(0, standard))
|
||||
default:
|
||||
return fmt.Errorf("cannot unmarshal %s into Time", string(data))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Time represents a time instance.
|
||||
func (a Time) Time() time.Time { return time.Time(a) }
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
|
||||
testsubs "github.com/thrasher-corp/gocryptotrader/internal/testing/subscriptions"
|
||||
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
// Please supply your own APIKEYS here for due diligence testing
|
||||
@@ -3192,7 +3193,7 @@ func TestParseGateioMilliSecTimeUnmarshal(t *testing.T) {
|
||||
float64JSON := `{"number": 1684981731.098}`
|
||||
|
||||
time := time.UnixMilli(timeWhenTesting)
|
||||
var in Time
|
||||
var in types.Time
|
||||
err := json.Unmarshal([]byte(timeWhenTestingString), &in)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -3201,7 +3202,7 @@ func TestParseGateioMilliSecTimeUnmarshal(t *testing.T) {
|
||||
t.Fatalf("found %v, but expected %v", in.Time(), time)
|
||||
}
|
||||
inInteger := struct {
|
||||
Number Time `json:"number"`
|
||||
Number types.Time `json:"number"`
|
||||
}{}
|
||||
err = json.Unmarshal([]byte(integerJSON), &inInteger)
|
||||
if err != nil {
|
||||
@@ -3212,7 +3213,7 @@ func TestParseGateioMilliSecTimeUnmarshal(t *testing.T) {
|
||||
}
|
||||
|
||||
inFloat64 := struct {
|
||||
Number Time `json:"number"`
|
||||
Number types.Time `json:"number"`
|
||||
}{}
|
||||
err = json.Unmarshal([]byte(float64JSON), &inFloat64)
|
||||
if err != nil {
|
||||
@@ -3232,7 +3233,7 @@ func TestParseTimeUnmarshal(t *testing.T) {
|
||||
timeWhenTestingStringMicroSecond := `"1691122380942.173000"`
|
||||
|
||||
whenTime := time.Unix(timeWhenTesting, 0)
|
||||
var in Time
|
||||
var in types.Time
|
||||
err := json.Unmarshal([]byte(timeWhenTestingString), &in)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -3241,7 +3242,7 @@ func TestParseTimeUnmarshal(t *testing.T) {
|
||||
t.Fatalf("found %v, but expected %v", in.Time(), whenTime)
|
||||
}
|
||||
inInteger := struct {
|
||||
Number Time `json:"number"`
|
||||
Number types.Time `json:"number"`
|
||||
}{}
|
||||
err = json.Unmarshal([]byte(integerJSON), &inInteger)
|
||||
if err != nil {
|
||||
@@ -3252,7 +3253,7 @@ func TestParseTimeUnmarshal(t *testing.T) {
|
||||
}
|
||||
|
||||
inFloat64 := struct {
|
||||
Number Time `json:"number"`
|
||||
Number types.Time `json:"number"`
|
||||
}{}
|
||||
err = json.Unmarshal([]byte(float64JSON), &inFloat64)
|
||||
if err != nil {
|
||||
@@ -3263,7 +3264,7 @@ func TestParseTimeUnmarshal(t *testing.T) {
|
||||
t.Fatalf("found %v, but expected %v", inFloat64.Number.Time(), msTime)
|
||||
}
|
||||
|
||||
var microSeconds Time
|
||||
var microSeconds types.Time
|
||||
err = json.Unmarshal([]byte(timeWhenTestingStringMicroSecond), µSeconds)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -3656,57 +3657,3 @@ func TestGenerateWebsocketMessageID(t *testing.T) {
|
||||
t.Parallel()
|
||||
require.NotEmpty(t, g.GenerateWebsocketMessageID(false))
|
||||
}
|
||||
|
||||
func TestTime(t *testing.T) {
|
||||
t.Parallel()
|
||||
var 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())
|
||||
|
||||
// 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())
|
||||
}
|
||||
|
||||
// 5046307 216.0 ns/op 168 B/op 2 allocs/op (current)
|
||||
// 2716176 441.9 ns/op 352 B/op 6 allocs/op (previous)
|
||||
func BenchmarkTime(b *testing.B) {
|
||||
var testTime Time
|
||||
for i := 0; i < b.N; i++ {
|
||||
err := json.Unmarshal([]byte(`"1691122380942.173000"`), &testTime)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
||||
"github.com/thrasher-corp/gocryptotrader/common/crypto"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
@@ -477,7 +476,7 @@ func (ku *Kucoin) GetSingleIsolatedMarginAccountInfo(ctx context.Context, symbol
|
||||
// GetCurrentServerTime gets the server time
|
||||
func (ku *Kucoin) GetCurrentServerTime(ctx context.Context) (time.Time, error) {
|
||||
resp := struct {
|
||||
Timestamp convert.ExchangeTime `json:"data"`
|
||||
Timestamp types.Time `json:"data"`
|
||||
Error
|
||||
}{}
|
||||
err := ku.SendHTTPRequest(ctx, exchange.RestSpot, currentServerTimeEPL, "/v1/timestamp", &resp)
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
@@ -286,7 +285,7 @@ func (ku *Kucoin) GetPublicFundingRate(ctx context.Context, symbol string, from,
|
||||
// GetFuturesServerTime get server time
|
||||
func (ku *Kucoin) GetFuturesServerTime(ctx context.Context) (time.Time, error) {
|
||||
resp := struct {
|
||||
Data convert.ExchangeTime `json:"data"`
|
||||
Data types.Time `json:"data"`
|
||||
Error
|
||||
}{}
|
||||
err := ku.SendHTTPRequest(ctx, exchange.RestFutures, futuresServerTimeEPL, "/v1/timestamp", &resp)
|
||||
|
||||
@@ -3,7 +3,6 @@ package kucoin
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
@@ -16,104 +15,104 @@ var (
|
||||
|
||||
// Contract store contract details
|
||||
type Contract struct {
|
||||
Symbol string `json:"symbol"`
|
||||
RootSymbol string `json:"rootSymbol"`
|
||||
ContractType string `json:"type"`
|
||||
FirstOpenDate convert.ExchangeTime `json:"firstOpenDate"`
|
||||
ExpireDate convert.ExchangeTime `json:"expireDate"`
|
||||
SettleDate convert.ExchangeTime `json:"settleDate"`
|
||||
BaseCurrency string `json:"baseCurrency"`
|
||||
QuoteCurrency string `json:"quoteCurrency"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
MaxOrderQty float64 `json:"maxOrderQty"`
|
||||
MaxPrice float64 `json:"maxPrice"`
|
||||
LotSize float64 `json:"lotSize"`
|
||||
TickSize float64 `json:"tickSize"`
|
||||
IndexPriceTickSize float64 `json:"indexPriceTickSize"`
|
||||
Multiplier float64 `json:"multiplier"`
|
||||
InitialMargin float64 `json:"initialMargin"`
|
||||
MaintainMargin float64 `json:"maintainMargin"`
|
||||
MaxRiskLimit float64 `json:"maxRiskLimit"`
|
||||
MinRiskLimit float64 `json:"minRiskLimit"`
|
||||
RiskStep float64 `json:"riskStep"`
|
||||
MakerFeeRate float64 `json:"makerFeeRate"`
|
||||
TakerFeeRate float64 `json:"takerFeeRate"`
|
||||
TakerFixFee float64 `json:"takerFixFee"`
|
||||
MakerFixFee float64 `json:"makerFixFee"`
|
||||
SettlementFee float64 `json:"settlementFee"`
|
||||
IsDeleverage bool `json:"isDeleverage"`
|
||||
IsQuanto bool `json:"isQuanto"`
|
||||
IsInverse bool `json:"isInverse"`
|
||||
MarkMethod string `json:"markMethod"`
|
||||
FairMethod string `json:"fairMethod"`
|
||||
FundingBaseSymbol string `json:"fundingBaseSymbol"`
|
||||
FundingQuoteSymbol string `json:"fundingQuoteSymbol"`
|
||||
FundingRateSymbol string `json:"fundingRateSymbol"`
|
||||
IndexSymbol string `json:"indexSymbol"`
|
||||
SettlementSymbol string `json:"settlementSymbol"`
|
||||
Status string `json:"status"`
|
||||
FundingFeeRate float64 `json:"fundingFeeRate"`
|
||||
PredictedFundingFeeRate float64 `json:"predictedFundingFeeRate"`
|
||||
OpenInterest types.Number `json:"openInterest"`
|
||||
TurnoverOf24h float64 `json:"turnoverOf24h"`
|
||||
VolumeOf24h float64 `json:"volumeOf24h"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
IndexPrice float64 `json:"indexPrice"`
|
||||
LastTradePrice float64 `json:"lastTradePrice"`
|
||||
NextFundingRateTime int64 `json:"nextFundingRateTime"`
|
||||
MaxLeverage float64 `json:"maxLeverage"`
|
||||
SourceExchanges []string `json:"sourceExchanges"`
|
||||
PremiumsSymbol1M string `json:"premiumsSymbol1M"`
|
||||
PremiumsSymbol8H string `json:"premiumsSymbol8H"`
|
||||
FundingBaseSymbol1M string `json:"fundingBaseSymbol1M"`
|
||||
FundingQuoteSymbol1M string `json:"fundingQuoteSymbol1M"`
|
||||
LowPrice float64 `json:"lowPrice"`
|
||||
HighPrice float64 `json:"highPrice"`
|
||||
PriceChgPct float64 `json:"priceChgPct"`
|
||||
PriceChg float64 `json:"priceChg"`
|
||||
Symbol string `json:"symbol"`
|
||||
RootSymbol string `json:"rootSymbol"`
|
||||
ContractType string `json:"type"`
|
||||
FirstOpenDate types.Time `json:"firstOpenDate"`
|
||||
ExpireDate types.Time `json:"expireDate"`
|
||||
SettleDate types.Time `json:"settleDate"`
|
||||
BaseCurrency string `json:"baseCurrency"`
|
||||
QuoteCurrency string `json:"quoteCurrency"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
MaxOrderQty float64 `json:"maxOrderQty"`
|
||||
MaxPrice float64 `json:"maxPrice"`
|
||||
LotSize float64 `json:"lotSize"`
|
||||
TickSize float64 `json:"tickSize"`
|
||||
IndexPriceTickSize float64 `json:"indexPriceTickSize"`
|
||||
Multiplier float64 `json:"multiplier"`
|
||||
InitialMargin float64 `json:"initialMargin"`
|
||||
MaintainMargin float64 `json:"maintainMargin"`
|
||||
MaxRiskLimit float64 `json:"maxRiskLimit"`
|
||||
MinRiskLimit float64 `json:"minRiskLimit"`
|
||||
RiskStep float64 `json:"riskStep"`
|
||||
MakerFeeRate float64 `json:"makerFeeRate"`
|
||||
TakerFeeRate float64 `json:"takerFeeRate"`
|
||||
TakerFixFee float64 `json:"takerFixFee"`
|
||||
MakerFixFee float64 `json:"makerFixFee"`
|
||||
SettlementFee float64 `json:"settlementFee"`
|
||||
IsDeleverage bool `json:"isDeleverage"`
|
||||
IsQuanto bool `json:"isQuanto"`
|
||||
IsInverse bool `json:"isInverse"`
|
||||
MarkMethod string `json:"markMethod"`
|
||||
FairMethod string `json:"fairMethod"`
|
||||
FundingBaseSymbol string `json:"fundingBaseSymbol"`
|
||||
FundingQuoteSymbol string `json:"fundingQuoteSymbol"`
|
||||
FundingRateSymbol string `json:"fundingRateSymbol"`
|
||||
IndexSymbol string `json:"indexSymbol"`
|
||||
SettlementSymbol string `json:"settlementSymbol"`
|
||||
Status string `json:"status"`
|
||||
FundingFeeRate float64 `json:"fundingFeeRate"`
|
||||
PredictedFundingFeeRate float64 `json:"predictedFundingFeeRate"`
|
||||
OpenInterest types.Number `json:"openInterest"`
|
||||
TurnoverOf24h float64 `json:"turnoverOf24h"`
|
||||
VolumeOf24h float64 `json:"volumeOf24h"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
IndexPrice float64 `json:"indexPrice"`
|
||||
LastTradePrice float64 `json:"lastTradePrice"`
|
||||
NextFundingRateTime int64 `json:"nextFundingRateTime"`
|
||||
MaxLeverage float64 `json:"maxLeverage"`
|
||||
SourceExchanges []string `json:"sourceExchanges"`
|
||||
PremiumsSymbol1M string `json:"premiumsSymbol1M"`
|
||||
PremiumsSymbol8H string `json:"premiumsSymbol8H"`
|
||||
FundingBaseSymbol1M string `json:"fundingBaseSymbol1M"`
|
||||
FundingQuoteSymbol1M string `json:"fundingQuoteSymbol1M"`
|
||||
LowPrice float64 `json:"lowPrice"`
|
||||
HighPrice float64 `json:"highPrice"`
|
||||
PriceChgPct float64 `json:"priceChgPct"`
|
||||
PriceChg float64 `json:"priceChg"`
|
||||
}
|
||||
|
||||
// FuturesTicker stores ticker data
|
||||
type FuturesTicker struct {
|
||||
Sequence int64 `json:"sequence"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side order.Side `json:"side"`
|
||||
Size float64 `json:"size"`
|
||||
Price types.Number `json:"price"`
|
||||
BestBidSize float64 `json:"bestBidSize"`
|
||||
BestBidPrice types.Number `json:"bestBidPrice"`
|
||||
BestAskSize float64 `json:"bestAskSize"`
|
||||
BestAskPrice types.Number `json:"bestAskPrice"`
|
||||
TradeID string `json:"tradeId"`
|
||||
FilledTime convert.ExchangeTime `json:"ts"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side order.Side `json:"side"`
|
||||
Size float64 `json:"size"`
|
||||
Price types.Number `json:"price"`
|
||||
BestBidSize float64 `json:"bestBidSize"`
|
||||
BestBidPrice types.Number `json:"bestBidPrice"`
|
||||
BestAskSize float64 `json:"bestAskSize"`
|
||||
BestAskPrice types.Number `json:"bestAskPrice"`
|
||||
TradeID string `json:"tradeId"`
|
||||
FilledTime types.Time `json:"ts"`
|
||||
}
|
||||
|
||||
type futuresOrderbookResponse struct {
|
||||
Asks [][2]float64 `json:"asks"`
|
||||
Bids [][2]float64 `json:"bids"`
|
||||
Time convert.ExchangeTime `json:"ts"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
Symbol string `json:"symbol"`
|
||||
Asks [][2]float64 `json:"asks"`
|
||||
Bids [][2]float64 `json:"bids"`
|
||||
Time types.Time `json:"ts"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
Symbol string `json:"symbol"`
|
||||
}
|
||||
|
||||
// FuturesTrade stores trade data
|
||||
type FuturesTrade struct {
|
||||
Sequence int64 `json:"sequence"`
|
||||
TradeID string `json:"tradeId"`
|
||||
TakerOrderID string `json:"takerOrderId"`
|
||||
MakerOrderID string `json:"makerOrderId"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size"`
|
||||
Side string `json:"side"`
|
||||
FilledTime convert.ExchangeTime `json:"ts"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
TradeID string `json:"tradeId"`
|
||||
TakerOrderID string `json:"takerOrderId"`
|
||||
MakerOrderID string `json:"makerOrderId"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size"`
|
||||
Side string `json:"side"`
|
||||
FilledTime types.Time `json:"ts"`
|
||||
}
|
||||
|
||||
// FuturesInterestRate stores interest rate data
|
||||
type FuturesInterestRate struct {
|
||||
Symbol string `json:"symbol"`
|
||||
TimePoint convert.ExchangeTime `json:"timePoint"`
|
||||
Value float64 `json:"value"`
|
||||
Granularity int64 `json:"granularity"`
|
||||
Symbol string `json:"symbol"`
|
||||
TimePoint types.Time `json:"timePoint"`
|
||||
Value float64 `json:"value"`
|
||||
Granularity int64 `json:"granularity"`
|
||||
}
|
||||
|
||||
// Decomposition stores decomposition data
|
||||
@@ -143,9 +142,9 @@ type FuturesFundingRate struct {
|
||||
|
||||
// FundingHistoryItem represents funding history item
|
||||
type FundingHistoryItem struct {
|
||||
Symbol string `json:"symbol"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
Timepoint convert.ExchangeTime `json:"timepoint"`
|
||||
Symbol string `json:"symbol"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
Timepoint types.Time `json:"timepoint"`
|
||||
}
|
||||
|
||||
// FuturesKline stores kline data
|
||||
@@ -169,42 +168,42 @@ type FutureOrdersResponse struct {
|
||||
|
||||
// FuturesOrder represents futures order information
|
||||
type FuturesOrder struct {
|
||||
ID string `json:"id"`
|
||||
Symbol string `json:"symbol"`
|
||||
OrderType string `json:"type"`
|
||||
Side string `json:"side"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size"`
|
||||
Value float64 `json:"value,string"`
|
||||
DealValue float64 `json:"dealValue,string"`
|
||||
DealSize float64 `json:"dealSize"`
|
||||
Stp string `json:"stp"`
|
||||
Stop string `json:"stop"`
|
||||
StopPriceType string `json:"stopPriceType"`
|
||||
StopTriggered bool `json:"stopTriggered"`
|
||||
StopPrice float64 `json:"stopPrice,string"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Iceberg bool `json:"iceberg"`
|
||||
Leverage float64 `json:"leverage,string"`
|
||||
ForceHold bool `json:"forceHold"`
|
||||
CloseOrder bool `json:"closeOrder"`
|
||||
VisibleSize float64 `json:"visibleSize"`
|
||||
ClientOid string `json:"clientOid"`
|
||||
Remark string `json:"remark"`
|
||||
Tags string `json:"tags"`
|
||||
IsActive bool `json:"isActive"`
|
||||
CancelExist bool `json:"cancelExist"`
|
||||
CreatedAt convert.ExchangeTime `json:"createdAt"`
|
||||
UpdatedAt convert.ExchangeTime `json:"updatedAt"`
|
||||
EndAt convert.ExchangeTime `json:"endAt"`
|
||||
OrderTime convert.ExchangeTime `json:"orderTime"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
Status string `json:"status"`
|
||||
FilledValue float64 `json:"filledValue,string"`
|
||||
FilledSize float64 `json:"filledSize"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
ID string `json:"id"`
|
||||
Symbol string `json:"symbol"`
|
||||
OrderType string `json:"type"`
|
||||
Side string `json:"side"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size"`
|
||||
Value float64 `json:"value,string"`
|
||||
DealValue float64 `json:"dealValue,string"`
|
||||
DealSize float64 `json:"dealSize"`
|
||||
Stp string `json:"stp"`
|
||||
Stop string `json:"stop"`
|
||||
StopPriceType string `json:"stopPriceType"`
|
||||
StopTriggered bool `json:"stopTriggered"`
|
||||
StopPrice float64 `json:"stopPrice,string"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Iceberg bool `json:"iceberg"`
|
||||
Leverage float64 `json:"leverage,string"`
|
||||
ForceHold bool `json:"forceHold"`
|
||||
CloseOrder bool `json:"closeOrder"`
|
||||
VisibleSize float64 `json:"visibleSize"`
|
||||
ClientOid string `json:"clientOid"`
|
||||
Remark string `json:"remark"`
|
||||
Tags string `json:"tags"`
|
||||
IsActive bool `json:"isActive"`
|
||||
CancelExist bool `json:"cancelExist"`
|
||||
CreatedAt types.Time `json:"createdAt"`
|
||||
UpdatedAt types.Time `json:"updatedAt"`
|
||||
EndAt types.Time `json:"endAt"`
|
||||
OrderTime types.Time `json:"orderTime"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
Status string `json:"status"`
|
||||
FilledValue float64 `json:"filledValue,string"`
|
||||
FilledSize float64 `json:"filledSize"`
|
||||
ReduceOnly bool `json:"reduceOnly"`
|
||||
}
|
||||
|
||||
// FutureFillsResponse represents a future fills list response detail
|
||||
@@ -218,25 +217,25 @@ type FutureFillsResponse struct {
|
||||
|
||||
// FuturesFill represents list of recent fills for futures orders
|
||||
type FuturesFill struct {
|
||||
Symbol string `json:"symbol"`
|
||||
TradeID string `json:"tradeId"`
|
||||
OrderID string `json:"orderId"`
|
||||
Side string `json:"side"`
|
||||
Liquidity string `json:"liquidity"`
|
||||
ForceTaker bool `json:"forceTaker"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size,string"`
|
||||
Value float64 `json:"value,string"`
|
||||
FeeRate float64 `json:"feeRate,string"`
|
||||
FixFee float64 `json:"fixFee,string"`
|
||||
FeeCurrency string `json:"feeCurrency"`
|
||||
Stop string `json:"stop"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
OrderType string `json:"orderType"`
|
||||
TradeType string `json:"tradeType"`
|
||||
CreatedAt convert.ExchangeTime `json:"createdAt"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
TradeTime convert.ExchangeTime `json:"tradeTime"`
|
||||
Symbol string `json:"symbol"`
|
||||
TradeID string `json:"tradeId"`
|
||||
OrderID string `json:"orderId"`
|
||||
Side string `json:"side"`
|
||||
Liquidity string `json:"liquidity"`
|
||||
ForceTaker bool `json:"forceTaker"`
|
||||
Price float64 `json:"price,string"`
|
||||
Size float64 `json:"size,string"`
|
||||
Value float64 `json:"value,string"`
|
||||
FeeRate float64 `json:"feeRate,string"`
|
||||
FixFee float64 `json:"fixFee,string"`
|
||||
FeeCurrency string `json:"feeCurrency"`
|
||||
Stop string `json:"stop"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
OrderType string `json:"orderType"`
|
||||
TradeType string `json:"tradeType"`
|
||||
CreatedAt types.Time `json:"createdAt"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
TradeTime types.Time `json:"tradeTime"`
|
||||
}
|
||||
|
||||
// FuturesOpenOrderStats represents futures open order summary stats information
|
||||
@@ -250,44 +249,44 @@ type FuturesOpenOrderStats struct {
|
||||
|
||||
// FuturesPosition represents futures position detailed information
|
||||
type FuturesPosition struct {
|
||||
ID string `json:"id"`
|
||||
Symbol string `json:"symbol"`
|
||||
AutoDeposit bool `json:"autoDeposit"`
|
||||
MaintMarginReq float64 `json:"maintMarginReq"`
|
||||
RiskLimit int64 `json:"riskLimit"`
|
||||
RealLeverage float64 `json:"realLeverage"`
|
||||
CrossMode bool `json:"crossMode"`
|
||||
ADLRankingPercentile float64 `json:"delevPercentage"`
|
||||
OpeningTimestamp convert.ExchangeTime `json:"openingTimestamp"`
|
||||
CurrentTimestamp convert.ExchangeTime `json:"currentTimestamp"`
|
||||
CurrentQty float64 `json:"currentQty"`
|
||||
CurrentCost float64 `json:"currentCost"` // Current position value
|
||||
CurrentComm float64 `json:"currentComm"` // Current commission
|
||||
UnrealisedCost float64 `json:"unrealisedCost"`
|
||||
RealisedGrossCost float64 `json:"realisedGrossCost"`
|
||||
RealisedCost float64 `json:"realisedCost"`
|
||||
IsOpen bool `json:"isOpen"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
MarkValue float64 `json:"markValue"`
|
||||
PosCost float64 `json:"posCost"` // Position value
|
||||
PosCross float64 `json:"posCross"` // Added margin
|
||||
PosInit float64 `json:"posInit"` // Leverage margin
|
||||
PosComm float64 `json:"posComm"` // Bankruptcy cost
|
||||
PosLoss float64 `json:"posLoss"` // Funding fees paid out
|
||||
PosMargin float64 `json:"posMargin"` // Position margin
|
||||
PosMaint float64 `json:"posMaint"` // Maintenance margin
|
||||
MaintMargin float64 `json:"maintMargin"`
|
||||
RealisedGrossPnl float64 `json:"realisedGrossPnl"`
|
||||
RealisedPnl float64 `json:"realisedPnl"`
|
||||
UnrealisedPnl float64 `json:"unrealisedPnl"`
|
||||
UnrealisedPnlPcnt float64 `json:"unrealisedPnlPcnt"`
|
||||
UnrealisedRoePcnt float64 `json:"unrealisedRoePcnt"`
|
||||
AvgEntryPrice float64 `json:"avgEntryPrice"`
|
||||
LiquidationPrice float64 `json:"liquidationPrice"`
|
||||
BankruptPrice float64 `json:"bankruptPrice"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
MaintainMargin float64 `json:"maintainMargin"`
|
||||
RiskLimitLevel int64 `json:"riskLimitLevel"`
|
||||
ID string `json:"id"`
|
||||
Symbol string `json:"symbol"`
|
||||
AutoDeposit bool `json:"autoDeposit"`
|
||||
MaintMarginReq float64 `json:"maintMarginReq"`
|
||||
RiskLimit int64 `json:"riskLimit"`
|
||||
RealLeverage float64 `json:"realLeverage"`
|
||||
CrossMode bool `json:"crossMode"`
|
||||
ADLRankingPercentile float64 `json:"delevPercentage"`
|
||||
OpeningTimestamp types.Time `json:"openingTimestamp"`
|
||||
CurrentTimestamp types.Time `json:"currentTimestamp"`
|
||||
CurrentQty float64 `json:"currentQty"`
|
||||
CurrentCost float64 `json:"currentCost"` // Current position value
|
||||
CurrentComm float64 `json:"currentComm"` // Current commission
|
||||
UnrealisedCost float64 `json:"unrealisedCost"`
|
||||
RealisedGrossCost float64 `json:"realisedGrossCost"`
|
||||
RealisedCost float64 `json:"realisedCost"`
|
||||
IsOpen bool `json:"isOpen"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
MarkValue float64 `json:"markValue"`
|
||||
PosCost float64 `json:"posCost"` // Position value
|
||||
PosCross float64 `json:"posCross"` // Added margin
|
||||
PosInit float64 `json:"posInit"` // Leverage margin
|
||||
PosComm float64 `json:"posComm"` // Bankruptcy cost
|
||||
PosLoss float64 `json:"posLoss"` // Funding fees paid out
|
||||
PosMargin float64 `json:"posMargin"` // Position margin
|
||||
PosMaint float64 `json:"posMaint"` // Maintenance margin
|
||||
MaintMargin float64 `json:"maintMargin"`
|
||||
RealisedGrossPnl float64 `json:"realisedGrossPnl"`
|
||||
RealisedPnl float64 `json:"realisedPnl"`
|
||||
UnrealisedPnl float64 `json:"unrealisedPnl"`
|
||||
UnrealisedPnlPcnt float64 `json:"unrealisedPnlPcnt"`
|
||||
UnrealisedRoePcnt float64 `json:"unrealisedRoePcnt"`
|
||||
AvgEntryPrice float64 `json:"avgEntryPrice"`
|
||||
LiquidationPrice float64 `json:"liquidationPrice"`
|
||||
BankruptPrice float64 `json:"bankruptPrice"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
MaintainMargin float64 `json:"maintainMargin"`
|
||||
RiskLimitLevel int64 `json:"riskLimitLevel"`
|
||||
}
|
||||
|
||||
// WithdrawMarginResponse represents a response data after withdrawing a margin
|
||||
@@ -315,15 +314,15 @@ type FuturesRiskLimitLevel struct {
|
||||
|
||||
// FuturesFundingHistory represents futures funding information
|
||||
type FuturesFundingHistory struct {
|
||||
ID string `json:"id"`
|
||||
Symbol string `json:"symbol"`
|
||||
Time convert.ExchangeTime `json:"timePoint"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
PositionQty float64 `json:"positionQty"`
|
||||
PositionCost float64 `json:"positionCost"`
|
||||
Funding float64 `json:"funding"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
ID string `json:"id"`
|
||||
Symbol string `json:"symbol"`
|
||||
Time types.Time `json:"timePoint"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
PositionQty float64 `json:"positionQty"`
|
||||
PositionCost float64 `json:"positionCost"`
|
||||
Funding float64 `json:"funding"`
|
||||
SettleCurrency string `json:"settleCurrency"`
|
||||
}
|
||||
|
||||
// FuturesAccount holds futures account detail information
|
||||
@@ -340,27 +339,27 @@ type FuturesAccount struct {
|
||||
|
||||
// FuturesTransactionHistory represents a transaction history
|
||||
type FuturesTransactionHistory struct {
|
||||
Time convert.ExchangeTime `json:"time"`
|
||||
Type string `json:"type"`
|
||||
Amount float64 `json:"amount"`
|
||||
Fee float64 `json:"fee"`
|
||||
AccountEquity float64 `json:"accountEquity"`
|
||||
Status string `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
Offset int64 `json:"offset"`
|
||||
Currency string `json:"currency"`
|
||||
Time types.Time `json:"time"`
|
||||
Type string `json:"type"`
|
||||
Amount float64 `json:"amount"`
|
||||
Fee float64 `json:"fee"`
|
||||
AccountEquity float64 `json:"accountEquity"`
|
||||
Status string `json:"status"`
|
||||
Remark string `json:"remark"`
|
||||
Offset int64 `json:"offset"`
|
||||
Currency string `json:"currency"`
|
||||
}
|
||||
|
||||
// APIKeyDetail represents the API key detail
|
||||
type APIKeyDetail struct {
|
||||
SubName string `json:"subName"`
|
||||
Remark string `json:"remark"`
|
||||
APIKey string `json:"apiKey"`
|
||||
APISecret string `json:"apiSecret"`
|
||||
Passphrase string `json:"passphrase"`
|
||||
Permission string `json:"permission"`
|
||||
IPWhitelist string `json:"ipWhitelist"`
|
||||
CreateAt convert.ExchangeTime `json:"createdAt"`
|
||||
SubName string `json:"subName"`
|
||||
Remark string `json:"remark"`
|
||||
APIKey string `json:"apiKey"`
|
||||
APISecret string `json:"apiSecret"`
|
||||
Passphrase string `json:"passphrase"`
|
||||
Permission string `json:"permission"`
|
||||
IPWhitelist string `json:"ipWhitelist"`
|
||||
CreateAt types.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
// FuturesDepositDetailsResponse represents a futures deposits list detail response
|
||||
@@ -374,14 +373,14 @@ type FuturesDepositDetailsResponse struct {
|
||||
|
||||
// FuturesDepositDetail represents futures deposit detail information
|
||||
type FuturesDepositDetail struct {
|
||||
Currency string `json:"currency"`
|
||||
Status string `json:"status"`
|
||||
Address string `json:"address"`
|
||||
IsInner bool `json:"isInner"`
|
||||
Amount float64 `json:"amount"`
|
||||
Fee float64 `json:"fee"`
|
||||
WalletTxID string `json:"walletTxId"`
|
||||
CreatedAt convert.ExchangeTime `json:"createdAt"`
|
||||
Currency string `json:"currency"`
|
||||
Status string `json:"status"`
|
||||
Address string `json:"address"`
|
||||
IsInner bool `json:"isInner"`
|
||||
Amount float64 `json:"amount"`
|
||||
Fee float64 `json:"fee"`
|
||||
WalletTxID string `json:"walletTxId"`
|
||||
CreatedAt types.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
// FuturesWithdrawalLimit represents withdrawal limit information
|
||||
@@ -410,44 +409,44 @@ type FuturesWithdrawalsListResponse struct {
|
||||
|
||||
// FuturesWithdrawalHistory represents a list of Futures withdrawal history
|
||||
type FuturesWithdrawalHistory struct {
|
||||
WithdrawalID string `json:"withdrawalId"`
|
||||
Currency string `json:"currency"`
|
||||
Status string `json:"status"`
|
||||
Address string `json:"address"`
|
||||
Memo string `json:"memo"`
|
||||
IsInner bool `json:"isInner"`
|
||||
Amount float64 `json:"amount"`
|
||||
Fee float64 `json:"fee"`
|
||||
WalletTxID string `json:"walletTxId"`
|
||||
CreatedAt convert.ExchangeTime `json:"createdAt"`
|
||||
Remark string `json:"remark"`
|
||||
Reason string `json:"reason"`
|
||||
WithdrawalID string `json:"withdrawalId"`
|
||||
Currency string `json:"currency"`
|
||||
Status string `json:"status"`
|
||||
Address string `json:"address"`
|
||||
Memo string `json:"memo"`
|
||||
IsInner bool `json:"isInner"`
|
||||
Amount float64 `json:"amount"`
|
||||
Fee float64 `json:"fee"`
|
||||
WalletTxID string `json:"walletTxId"`
|
||||
CreatedAt types.Time `json:"createdAt"`
|
||||
Remark string `json:"remark"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// TransferBase represents transfer base information
|
||||
type TransferBase struct {
|
||||
ApplyID string `json:"applyId"`
|
||||
Currency string `json:"currency"`
|
||||
RecRemark string `json:"recRemark"`
|
||||
RecSystem string `json:"recSystem"`
|
||||
Status string `json:"status"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Reason string `json:"reason"`
|
||||
CreatedAt convert.ExchangeTime `json:"createdAt"`
|
||||
Remark string `json:"remark"`
|
||||
ApplyID string `json:"applyId"`
|
||||
Currency string `json:"currency"`
|
||||
RecRemark string `json:"recRemark"`
|
||||
RecSystem string `json:"recSystem"`
|
||||
Status string `json:"status"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Reason string `json:"reason"`
|
||||
CreatedAt types.Time `json:"createdAt"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
// TransferRes represents a transfer response
|
||||
type TransferRes struct {
|
||||
TransferBase
|
||||
BizNo string `json:"bizNo"`
|
||||
PayAccountType string `json:"payAccountType"`
|
||||
PayTag string `json:"payTag"`
|
||||
RecAccountType string `json:"recAccountType"`
|
||||
RecTag string `json:"recTag"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Serial int64 `json:"sn"`
|
||||
UpdatedAt convert.ExchangeTime `json:"updatedAt"`
|
||||
BizNo string `json:"bizNo"`
|
||||
PayAccountType string `json:"payAccountType"`
|
||||
PayTag string `json:"payTag"`
|
||||
RecAccountType string `json:"recAccountType"`
|
||||
RecTag string `json:"recTag"`
|
||||
Fee float64 `json:"fee,string"`
|
||||
Serial int64 `json:"sn"`
|
||||
UpdatedAt types.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// TransferListsResponse represents a transfer lists detail
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,6 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
||||
@@ -2169,16 +2168,16 @@ type BlockTicker struct {
|
||||
|
||||
// BlockTrade represents a block trade.
|
||||
type BlockTrade struct {
|
||||
InstrumentID string `json:"instId"`
|
||||
TradeID string `json:"tradeId"`
|
||||
Price types.Number `json:"px"`
|
||||
Size types.Number `json:"sz"`
|
||||
Side order.Side `json:"side"`
|
||||
FillVolatility types.Number `json:"fillVol"`
|
||||
ForwardPrice types.Number `json:"fwdPx"`
|
||||
IndexPrice types.Number `json:"idxPx"`
|
||||
MarkPrice types.Number `json:"markPx"`
|
||||
Timestamp convert.ExchangeTime `json:"ts"`
|
||||
InstrumentID string `json:"instId"`
|
||||
TradeID string `json:"tradeId"`
|
||||
Price types.Number `json:"px"`
|
||||
Size types.Number `json:"sz"`
|
||||
Side order.Side `json:"side"`
|
||||
FillVolatility types.Number `json:"fillVol"`
|
||||
ForwardPrice types.Number `json:"fwdPx"`
|
||||
IndexPrice types.Number `json:"idxPx"`
|
||||
MarkPrice types.Number `json:"markPx"`
|
||||
Timestamp types.Time `json:"ts"`
|
||||
}
|
||||
|
||||
// UnitConvertResponse unit convert response.
|
||||
|
||||
79
types/time.go
Normal file
79
types/time.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Time represents a time.Time object that can be unmarshalled from a float64 or string.
|
||||
// MarshalJSON serializes the time to JSON using RFC 3339 format.
|
||||
// Note: Not all exchanges may support RFC 3339 for outbound requests, so ensure compatibility with each exchange's time
|
||||
// format requirements.
|
||||
type Time time.Time
|
||||
|
||||
// UnmarshalJSON deserializes json, and timestamp information.
|
||||
func (t *Time) UnmarshalJSON(data []byte) error {
|
||||
s := string(data)
|
||||
|
||||
switch s {
|
||||
case "null", "0", `""`, `"0"`:
|
||||
*t = Time(time.Time{})
|
||||
return nil
|
||||
}
|
||||
|
||||
if s[0] == '"' {
|
||||
s = s[1 : len(s)-1]
|
||||
}
|
||||
|
||||
if target := strings.Index(s, "."); target != -1 {
|
||||
s = s[:target] + s[target+1:]
|
||||
}
|
||||
|
||||
standard, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch len(s) {
|
||||
case 10:
|
||||
// Seconds
|
||||
*t = Time(time.Unix(standard, 0))
|
||||
case 11, 12:
|
||||
// Milliseconds: 1726104395.5 && 1726104395.56
|
||||
*t = Time(time.UnixMilli(standard * int64(math.Pow10(13-len(s)))))
|
||||
case 13:
|
||||
// Milliseconds
|
||||
*t = Time(time.UnixMilli(standard))
|
||||
case 14:
|
||||
// MicroSeconds: 1726106210903.0
|
||||
*t = Time(time.UnixMicro(standard * 100))
|
||||
case 16:
|
||||
// MicroSeconds
|
||||
*t = Time(time.UnixMicro(standard))
|
||||
case 17:
|
||||
// NanoSeconds: 1606292218213.4578
|
||||
*t = Time(time.Unix(0, standard*100))
|
||||
case 19:
|
||||
// NanoSeconds
|
||||
*t = Time(time.Unix(0, standard))
|
||||
default:
|
||||
return fmt.Errorf("cannot unmarshal %s into Time", string(data))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Time represents a time instance.
|
||||
func (t Time) Time() time.Time { return time.Time(t) }
|
||||
|
||||
// String returns a string representation of the time.
|
||||
func (t Time) String() string {
|
||||
return t.Time().String()
|
||||
}
|
||||
|
||||
// MarshalJSON serializes the time to json.
|
||||
func (t Time) MarshalJSON() ([]byte, error) {
|
||||
return t.Time().MarshalJSON()
|
||||
}
|
||||
86
types/time_test.go
Normal file
86
types/time_test.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
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())
|
||||
|
||||
// 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))
|
||||
}
|
||||
|
||||
// 5046307 216.0 ns/op 168 B/op 2 allocs/op (current)
|
||||
// 2716176 441.9 ns/op 352 B/op 6 allocs/op (previous)
|
||||
func BenchmarkUnmarshalJSON(b *testing.B) {
|
||||
var testTime Time
|
||||
for i := 0; i < b.N; i++ {
|
||||
err := json.Unmarshal([]byte(`"1691122380942.173000"`), &testTime)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTime(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTime := Time(time.Time{})
|
||||
assert.Equal(t, time.Time{}, testTime.Time())
|
||||
assert.Equal(t, "0001-01-01 00:00:00 +0000 UTC", testTime.String())
|
||||
}
|
||||
|
||||
func TestTime_MarshalJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTime := Time(time.Time{})
|
||||
data, err := testTime.MarshalJSON()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, `"0001-01-01T00:00:00Z"`, string(data))
|
||||
}
|
||||
Reference in New Issue
Block a user