mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
exchanges: Use singular futures settlement currency (#2092)
* Change settlement to singular currency * whoops.go * bitmex fix * minor updates * 64 divided by 2 * whoops2.go * ROBOT ROCK Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * ROCK ROCK ROCK ROCK ROBOT Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * shazNit * currencies unmarshal and code use * Update currency/currencies.go Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com> * Update exchanges/btse/btse_wrapper.go Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com> * reuse comment for better clarity * collapses entire thing * shazLint --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Gareth Kirwan <gbjkirwan@gmail.com>
This commit is contained in:
@@ -43,7 +43,6 @@ const (
|
||||
bitmexEndpointActiveIntervals = "/instrument/activeIntervals"
|
||||
bitmexEndpointCompositeIndex = "/instrument/compositeIndex"
|
||||
bitmexEndpointIndices = "/instrument/indices"
|
||||
bitmexEndpointInsuranceHistory = "/insurance"
|
||||
bitmexEndpointLiquidation = "/liquidation"
|
||||
bitmexEndpointLeader = "/leaderboard"
|
||||
bitmexEndpointAlias = "/leaderboard/name"
|
||||
@@ -70,7 +69,6 @@ const (
|
||||
bitmexEndpointCancelAllOrders = "/order/all"
|
||||
bitmexEndpointBulk = "/order/bulk"
|
||||
bitmexEndpointCancelOrderAfter = "/order/cancelAllAfter"
|
||||
bitmexEndpointClosePosition = "/order/closePosition"
|
||||
bitmexEndpointPosition = "/position"
|
||||
bitmexEndpointIsolatePosition = "/position/isolate"
|
||||
bitmexEndpointLeveragePosition = "/position/leverage"
|
||||
@@ -82,7 +80,6 @@ const (
|
||||
bitmexEndpointUserCommision = "/user/commission"
|
||||
bitmexEndpointUserConfirmEmail = "/user/confirmEmail"
|
||||
bitmexEndpointUserConfirmTFA = "/user/confirmEnableTFA"
|
||||
bitmexEndpointUserConfirmWithdrawal = "/user/confirmWithdrawal"
|
||||
bitmexEndpointUserDepositAddress = "/user/depositAddress"
|
||||
bitmexEndpointUserDisableTFA = "/user/disableTFA"
|
||||
bitmexEndpointUserLogout = "/user/logout"
|
||||
@@ -96,15 +93,7 @@ const (
|
||||
bitmexEndpointUserRequestWithdraw = "/user/requestWithdrawal"
|
||||
|
||||
constSatoshiBTC = 1e-08
|
||||
|
||||
// ContractPerpetual perpetual contract type
|
||||
ContractPerpetual = iota
|
||||
// ContractFutures futures contract type
|
||||
ContractFutures
|
||||
// ContractDownsideProfit downside profit contract type
|
||||
ContractDownsideProfit
|
||||
// ContractUpsideProfit upside profit contract type
|
||||
ContractUpsideProfit
|
||||
countLimit = uint32(1000)
|
||||
|
||||
perpetualContractID = "FFWCSX"
|
||||
spotID = "IFXXXP"
|
||||
|
||||
@@ -186,7 +186,7 @@ type GenericRequestParams struct {
|
||||
Columns string `json:"columns,omitempty"`
|
||||
|
||||
// Count - Number of results to fetch.
|
||||
Count int32 `json:"count,omitempty"`
|
||||
Count uint32 `json:"count,omitempty"`
|
||||
|
||||
// EndTime - Ending date filter for results.
|
||||
EndTime string `json:"endTime,omitempty"`
|
||||
|
||||
@@ -122,107 +122,107 @@ type Funding struct {
|
||||
|
||||
// Instrument Tradeable Contracts, Indices, and History
|
||||
type Instrument struct {
|
||||
AskPrice float64 `json:"askPrice"`
|
||||
BankruptLimitDownPrice float64 `json:"bankruptLimitDownPrice"`
|
||||
BankruptLimitUpPrice float64 `json:"bankruptLimitUpPrice"`
|
||||
BidPrice float64 `json:"bidPrice"`
|
||||
BuyLeg string `json:"buyLeg"`
|
||||
CalcInterval string `json:"calcInterval"`
|
||||
Capped bool `json:"capped"`
|
||||
ClosingTimestamp time.Time `json:"closingTimestamp"`
|
||||
Deleverage bool `json:"deleverage"`
|
||||
Expiry string `json:"expiry"`
|
||||
FairBasis float64 `json:"fairBasis"`
|
||||
FairBasisRate float64 `json:"fairBasisRate"`
|
||||
FairMethod string `json:"fairMethod"`
|
||||
FairPrice float64 `json:"fairPrice"`
|
||||
Front string `json:"front"`
|
||||
FundingBaseSymbol string `json:"fundingBaseSymbol"`
|
||||
FundingInterval time.Time `json:"fundingInterval"`
|
||||
FundingPremiumSymbol string `json:"fundingPremiumSymbol"`
|
||||
FundingQuoteSymbol string `json:"fundingQuoteSymbol"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
FundingTimestamp time.Time `json:"fundingTimestamp"`
|
||||
HasLiquidity bool `json:"hasLiquidity"`
|
||||
HighPrice float64 `json:"highPrice"`
|
||||
ImpactAskPrice float64 `json:"impactAskPrice"`
|
||||
ImpactBidPrice float64 `json:"impactBidPrice"`
|
||||
ImpactMidPrice float64 `json:"impactMidPrice"`
|
||||
IndicativeFundingRate float64 `json:"indicativeFundingRate"`
|
||||
IndicativeSettlePrice float64 `json:"indicativeSettlePrice"`
|
||||
IndicativeTaxRate float64 `json:"indicativeTaxRate"`
|
||||
InitMargin float64 `json:"initMargin"`
|
||||
InsuranceFee float64 `json:"insuranceFee"`
|
||||
InverseLeg string `json:"inverseLeg"`
|
||||
IsInverse bool `json:"isInverse"`
|
||||
IsQuanto bool `json:"isQuanto"`
|
||||
LastChangePcnt float64 `json:"lastChangePcnt"`
|
||||
LastPrice float64 `json:"lastPrice"`
|
||||
LastPriceProtected float64 `json:"lastPriceProtected"`
|
||||
LastTickDirection string `json:"lastTickDirection"`
|
||||
Limit float64 `json:"limit"`
|
||||
LimitDownPrice float64 `json:"limitDownPrice"`
|
||||
LimitUpPrice float64 `json:"limitUpPrice"`
|
||||
Listing string `json:"listing"`
|
||||
LotSize float64 `json:"lotSize"`
|
||||
LowPrice float64 `json:"lowPrice"`
|
||||
MaintMargin float64 `json:"maintMargin"`
|
||||
MakerFee float64 `json:"makerFee"`
|
||||
MarkMethod string `json:"markMethod"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
MaxOrderQty float64 `json:"maxOrderQty"`
|
||||
MaxPrice float64 `json:"maxPrice"`
|
||||
MidPrice float64 `json:"midPrice"`
|
||||
Multiplier float64 `json:"multiplier"`
|
||||
OpenInterest float64 `json:"openInterest"`
|
||||
OpenValue float64 `json:"openValue"`
|
||||
OpeningTimestamp time.Time `json:"openingTimestamp"`
|
||||
OptionMultiplier float64 `json:"optionMultiplier"`
|
||||
OptionStrikePcnt float64 `json:"optionStrikePcnt"`
|
||||
OptionStrikePrice float64 `json:"optionStrikePrice"`
|
||||
OptionStrikeRound float64 `json:"optionStrikeRound"`
|
||||
OptionUnderlyingPrice float64 `json:"optionUnderlyingPrice"`
|
||||
PositionCurrency string `json:"positionCurrency"`
|
||||
PrevClosePrice float64 `json:"prevClosePrice"`
|
||||
PrevPrice24h float64 `json:"prevPrice24h"`
|
||||
PrevTotalTurnover float64 `json:"prevTotalTurnover"`
|
||||
PrevTotalVolume float64 `json:"prevTotalVolume"`
|
||||
PublishInterval string `json:"publishInterval"`
|
||||
PublishTime time.Time `json:"publishTime"`
|
||||
QuoteCurrency string `json:"quoteCurrency"`
|
||||
QuoteToSettleMultiplier int64 `json:"quoteToSettleMultiplier"`
|
||||
RebalanceInterval string `json:"rebalanceInterval"`
|
||||
RebalanceTimestamp time.Time `json:"rebalanceTimestamp"`
|
||||
Reference string `json:"reference"`
|
||||
ReferenceSymbol string `json:"referenceSymbol"`
|
||||
RelistInterval string `json:"relistInterval"`
|
||||
RiskLimit float64 `json:"riskLimit"`
|
||||
RiskStep float64 `json:"riskStep"`
|
||||
RootSymbol string `json:"rootSymbol"`
|
||||
SellLeg string `json:"sellLeg"`
|
||||
SessionInterval string `json:"sessionInterval"`
|
||||
SettlCurrency string `json:"settlCurrency"`
|
||||
Settle string `json:"settle"`
|
||||
SettledPrice float64 `json:"settledPrice"`
|
||||
SettlementFee float64 `json:"settlementFee"`
|
||||
State string `json:"state"`
|
||||
Symbol string `json:"symbol"`
|
||||
TakerFee float64 `json:"takerFee"`
|
||||
Taxed bool `json:"taxed"`
|
||||
TickSize float64 `json:"tickSize"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
TotalTurnover float64 `json:"totalTurnover"`
|
||||
TotalVolume float64 `json:"totalVolume"`
|
||||
Turnover float64 `json:"turnover"`
|
||||
Turnover24h float64 `json:"turnover24h"`
|
||||
Typ string `json:"typ"`
|
||||
Underlying string `json:"underlying"`
|
||||
UnderlyingSymbol string `json:"underlyingSymbol"`
|
||||
UnderlyingToPositionMultiplier float64 `json:"underlyingToPositionMultiplier"`
|
||||
UnderlyingToSettleMultiplier float64 `json:"underlyingToSettleMultiplier"`
|
||||
Volume float64 `json:"volume"`
|
||||
Volume24h float64 `json:"volume24h"`
|
||||
Vwap float64 `json:"vwap"`
|
||||
AskPrice float64 `json:"askPrice"`
|
||||
BankruptLimitDownPrice float64 `json:"bankruptLimitDownPrice"`
|
||||
BankruptLimitUpPrice float64 `json:"bankruptLimitUpPrice"`
|
||||
BidPrice float64 `json:"bidPrice"`
|
||||
BuyLeg string `json:"buyLeg"`
|
||||
CalcInterval string `json:"calcInterval"`
|
||||
Capped bool `json:"capped"`
|
||||
ClosingTimestamp time.Time `json:"closingTimestamp"`
|
||||
Deleverage bool `json:"deleverage"`
|
||||
Expiry string `json:"expiry"`
|
||||
FairBasis float64 `json:"fairBasis"`
|
||||
FairBasisRate float64 `json:"fairBasisRate"`
|
||||
FairMethod string `json:"fairMethod"`
|
||||
FairPrice float64 `json:"fairPrice"`
|
||||
Front string `json:"front"`
|
||||
FundingBaseSymbol string `json:"fundingBaseSymbol"`
|
||||
FundingInterval time.Time `json:"fundingInterval"`
|
||||
FundingPremiumSymbol string `json:"fundingPremiumSymbol"`
|
||||
FundingQuoteSymbol string `json:"fundingQuoteSymbol"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
FundingTimestamp time.Time `json:"fundingTimestamp"`
|
||||
HasLiquidity bool `json:"hasLiquidity"`
|
||||
HighPrice float64 `json:"highPrice"`
|
||||
ImpactAskPrice float64 `json:"impactAskPrice"`
|
||||
ImpactBidPrice float64 `json:"impactBidPrice"`
|
||||
ImpactMidPrice float64 `json:"impactMidPrice"`
|
||||
IndicativeFundingRate float64 `json:"indicativeFundingRate"`
|
||||
IndicativeSettlePrice float64 `json:"indicativeSettlePrice"`
|
||||
IndicativeTaxRate float64 `json:"indicativeTaxRate"`
|
||||
InitMargin float64 `json:"initMargin"`
|
||||
InsuranceFee float64 `json:"insuranceFee"`
|
||||
InverseLeg string `json:"inverseLeg"`
|
||||
IsInverse bool `json:"isInverse"`
|
||||
IsQuanto bool `json:"isQuanto"`
|
||||
LastChangePcnt float64 `json:"lastChangePcnt"`
|
||||
LastPrice float64 `json:"lastPrice"`
|
||||
LastPriceProtected float64 `json:"lastPriceProtected"`
|
||||
LastTickDirection string `json:"lastTickDirection"`
|
||||
Limit float64 `json:"limit"`
|
||||
LimitDownPrice float64 `json:"limitDownPrice"`
|
||||
LimitUpPrice float64 `json:"limitUpPrice"`
|
||||
Listing string `json:"listing"`
|
||||
LotSize float64 `json:"lotSize"`
|
||||
LowPrice float64 `json:"lowPrice"`
|
||||
MaintMargin float64 `json:"maintMargin"`
|
||||
MakerFee float64 `json:"makerFee"`
|
||||
MarkMethod string `json:"markMethod"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
MaxOrderQty float64 `json:"maxOrderQty"`
|
||||
MaxPrice float64 `json:"maxPrice"`
|
||||
MidPrice float64 `json:"midPrice"`
|
||||
Multiplier float64 `json:"multiplier"`
|
||||
OpenInterest float64 `json:"openInterest"`
|
||||
OpenValue float64 `json:"openValue"`
|
||||
OpeningTimestamp time.Time `json:"openingTimestamp"`
|
||||
OptionMultiplier float64 `json:"optionMultiplier"`
|
||||
OptionStrikePcnt float64 `json:"optionStrikePcnt"`
|
||||
OptionStrikePrice float64 `json:"optionStrikePrice"`
|
||||
OptionStrikeRound float64 `json:"optionStrikeRound"`
|
||||
OptionUnderlyingPrice float64 `json:"optionUnderlyingPrice"`
|
||||
PositionCurrency string `json:"positionCurrency"`
|
||||
PrevClosePrice float64 `json:"prevClosePrice"`
|
||||
PrevPrice24h float64 `json:"prevPrice24h"`
|
||||
PrevTotalTurnover float64 `json:"prevTotalTurnover"`
|
||||
PrevTotalVolume float64 `json:"prevTotalVolume"`
|
||||
PublishInterval string `json:"publishInterval"`
|
||||
PublishTime time.Time `json:"publishTime"`
|
||||
QuoteCurrency string `json:"quoteCurrency"`
|
||||
QuoteToSettleMultiplier int64 `json:"quoteToSettleMultiplier"`
|
||||
RebalanceInterval string `json:"rebalanceInterval"`
|
||||
RebalanceTimestamp time.Time `json:"rebalanceTimestamp"`
|
||||
Reference string `json:"reference"`
|
||||
ReferenceSymbol string `json:"referenceSymbol"`
|
||||
RelistInterval string `json:"relistInterval"`
|
||||
RiskLimit float64 `json:"riskLimit"`
|
||||
RiskStep float64 `json:"riskStep"`
|
||||
RootSymbol string `json:"rootSymbol"`
|
||||
SellLeg string `json:"sellLeg"`
|
||||
SessionInterval string `json:"sessionInterval"`
|
||||
SettlementCurrency currency.Code `json:"settlCurrency"`
|
||||
Settle string `json:"settle"`
|
||||
SettledPrice float64 `json:"settledPrice"`
|
||||
SettlementFee float64 `json:"settlementFee"`
|
||||
State string `json:"state"`
|
||||
Symbol string `json:"symbol"`
|
||||
TakerFee float64 `json:"takerFee"`
|
||||
Taxed bool `json:"taxed"`
|
||||
TickSize float64 `json:"tickSize"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
TotalTurnover float64 `json:"totalTurnover"`
|
||||
TotalVolume float64 `json:"totalVolume"`
|
||||
Turnover float64 `json:"turnover"`
|
||||
Turnover24h float64 `json:"turnover24h"`
|
||||
Typ string `json:"typ"`
|
||||
Underlying string `json:"underlying"`
|
||||
UnderlyingSymbol string `json:"underlyingSymbol"`
|
||||
UnderlyingToPositionMultiplier float64 `json:"underlyingToPositionMultiplier"`
|
||||
UnderlyingToSettleMultiplier float64 `json:"underlyingToSettleMultiplier"`
|
||||
Volume float64 `json:"volume"`
|
||||
Volume24h float64 `json:"volume24h"`
|
||||
Vwap float64 `json:"vwap"`
|
||||
}
|
||||
|
||||
// InstrumentInterval instrument interval
|
||||
|
||||
@@ -533,10 +533,9 @@ func (e *Exchange) GetHistoricTrades(ctx context.Context, p currency.Pair, asset
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
limit := 1000
|
||||
req := &GenericRequestParams{
|
||||
Symbol: p.String(),
|
||||
Count: int32(limit),
|
||||
Count: countLimit,
|
||||
EndTime: timestampEnd.UTC().Format("2006-01-02T15:04:05.000Z"),
|
||||
}
|
||||
ts := timestampStart
|
||||
@@ -581,7 +580,7 @@ allTrades:
|
||||
ts = tradeData[i].Timestamp
|
||||
}
|
||||
}
|
||||
if len(tradeData) != limit {
|
||||
if len(tradeData) != int(countLimit) {
|
||||
break allTrades
|
||||
}
|
||||
}
|
||||
@@ -984,25 +983,18 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
if !e.SupportsAsset(item) || item == asset.Index {
|
||||
return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, item)
|
||||
}
|
||||
|
||||
marketInfo, err := e.GetInstruments(ctx, &GenericRequestParams{Reverse: true, Count: 500})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := make([]futures.Contract, 0, len(marketInfo))
|
||||
var resp []futures.Contract
|
||||
switch item {
|
||||
case asset.PerpetualContract:
|
||||
marketInfo, err := e.GetInstruments(ctx, &GenericRequestParams{
|
||||
Count: countLimit,
|
||||
Filter: `{"typ": "` + perpetualContractID + `"}`,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for x := range marketInfo {
|
||||
if marketInfo[x].Typ != perpetualContractID {
|
||||
continue
|
||||
}
|
||||
var cp, underlying currency.Pair
|
||||
cp, err = currency.NewPairFromStrings(marketInfo[x].RootSymbol, marketInfo[x].QuoteCurrency)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
underlying, err = currency.NewPairFromStrings(marketInfo[x].RootSymbol, marketInfo[x].SettlCurrency)
|
||||
cp, err := currency.NewPairFromStrings(marketInfo[x].RootSymbol, marketInfo[x].QuoteCurrency)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1023,17 +1015,17 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
contractSettlementType = futures.Inverse
|
||||
}
|
||||
resp = append(resp, futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: s,
|
||||
IsActive: marketInfo[x].State == "Open",
|
||||
Status: marketInfo[x].State,
|
||||
Type: futures.Perpetual,
|
||||
SettlementType: contractSettlementType,
|
||||
SettlementCurrencies: currency.Currencies{currency.NewCode(marketInfo[x].SettlCurrency)},
|
||||
Multiplier: marketInfo[x].Multiplier,
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: currency.NewPair(cp.Base, marketInfo[x].SettlementCurrency),
|
||||
Asset: item,
|
||||
StartDate: s,
|
||||
IsActive: marketInfo[x].State == "Open",
|
||||
Status: marketInfo[x].State,
|
||||
Type: futures.Perpetual,
|
||||
SettlementType: contractSettlementType,
|
||||
SettlementCurrency: marketInfo[x].SettlementCurrency,
|
||||
Multiplier: marketInfo[x].Multiplier,
|
||||
LatestRate: fundingrate.Rate{
|
||||
Time: marketInfo[x].FundingTimestamp,
|
||||
Rate: decimal.NewFromFloat(marketInfo[x].FundingRate),
|
||||
@@ -1041,16 +1033,16 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
})
|
||||
}
|
||||
case asset.Futures:
|
||||
marketInfo, err := e.GetInstruments(ctx, &GenericRequestParams{
|
||||
Count: countLimit,
|
||||
Filter: `{"typ": "` + futuresID + `"}`,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for x := range marketInfo {
|
||||
if marketInfo[x].Typ != futuresID {
|
||||
continue
|
||||
}
|
||||
var cp, underlying currency.Pair
|
||||
cp, err = currency.NewPairFromStrings(marketInfo[x].RootSymbol, marketInfo[x].Symbol[len(marketInfo[x].RootSymbol):])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
underlying, err = currency.NewPairFromStrings(marketInfo[x].RootSymbol, marketInfo[x].SettlCurrency)
|
||||
cp, err := currency.NewPairFromStrings(marketInfo[x].RootSymbol, marketInfo[x].Symbol[len(marketInfo[x].RootSymbol):])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1093,18 +1085,18 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
contractSettlementType = futures.Quanto
|
||||
}
|
||||
resp = append(resp, futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: startTime,
|
||||
EndDate: endTime,
|
||||
IsActive: marketInfo[x].State == "Open",
|
||||
Status: marketInfo[x].State,
|
||||
Type: ct,
|
||||
SettlementCurrencies: currency.Currencies{currency.NewCode(marketInfo[x].SettlCurrency)},
|
||||
Multiplier: marketInfo[x].Multiplier,
|
||||
SettlementType: contractSettlementType,
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: currency.NewPair(cp.Base, marketInfo[x].SettlementCurrency),
|
||||
Asset: item,
|
||||
StartDate: startTime,
|
||||
EndDate: endTime,
|
||||
IsActive: marketInfo[x].State == "Open",
|
||||
Status: marketInfo[x].State,
|
||||
Type: ct,
|
||||
SettlementCurrency: marketInfo[x].SettlementCurrency,
|
||||
Multiplier: marketInfo[x].Multiplier,
|
||||
SettlementType: contractSettlementType,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/fundingrate"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/futures"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||
@@ -642,10 +641,7 @@ func TestWsUnexpectedData(t *testing.T) {
|
||||
|
||||
func TestGetFuturesContractDetails(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := e.GetFuturesContractDetails(t.Context(), asset.Spot)
|
||||
assert.ErrorIs(t, err, futures.ErrNotFuturesAsset, "GetFuturesContractDetails should error correctly on Spot")
|
||||
|
||||
_, err = e.GetFuturesContractDetails(t.Context(), asset.USDTMarginedFutures)
|
||||
_, err := e.GetFuturesContractDetails(t.Context(), asset.Margin)
|
||||
assert.ErrorIs(t, err, asset.ErrNotSupported, "GetFuturesContractDetails should error correctly on Margin")
|
||||
|
||||
_, err = e.GetFuturesContractDetails(t.Context(), asset.Futures)
|
||||
@@ -771,18 +767,18 @@ func TestMarketPair(t *testing.T) {
|
||||
|
||||
for _, tt := range []struct {
|
||||
symbol string
|
||||
base string
|
||||
base currency.Code
|
||||
futures bool
|
||||
expectedErr error
|
||||
expectedSymbol string
|
||||
}{
|
||||
{symbol: "RUNEPFC", base: currency.RUNE.String(), futures: true, expectedSymbol: "RUNEPFC"},
|
||||
{symbol: "TRUMPPFC", base: "TRUMPSOL", futures: true, expectedSymbol: "TRUMPPFC"},
|
||||
{symbol: "BTCUSD", base: "NAUGHTYBASE", futures: true, expectedErr: errInvalidPairSymbol},
|
||||
{symbol: "NAUGHTYSYMBOL", base: currency.BTC.String(), expectedErr: errInvalidPairSymbol},
|
||||
{symbol: "BTC-USD", base: currency.BTC.String(), expectedSymbol: "BTCUSD"},
|
||||
{symbol: "RUNEPFC", base: currency.RUNE, futures: true, expectedSymbol: "RUNEPFC"},
|
||||
{symbol: "TRUMPPFC", base: currency.NewCode("TRUMPSOL"), futures: true, expectedSymbol: "TRUMPPFC"},
|
||||
{symbol: "BTCUSD", base: currency.NewCode("NAUGHTYBASE"), futures: true, expectedErr: errInvalidPairSymbol},
|
||||
{symbol: "NAUGHTYSYMBOL", base: currency.BTC, expectedErr: errInvalidPairSymbol},
|
||||
{symbol: "BTC-USD", base: currency.BTC, expectedSymbol: "BTCUSD"},
|
||||
} {
|
||||
mp := MarketPair{Symbol: tt.symbol, Base: tt.base, Quote: "USD", Futures: tt.futures}
|
||||
mp := MarketPair{Symbol: tt.symbol, Base: tt.base, Quote: currency.USD, Futures: tt.futures}
|
||||
p, err := mp.Pair()
|
||||
assert.ErrorIs(t, err, tt.expectedErr, "Pair should not error")
|
||||
assert.Equal(t, tt.expectedSymbol, p.String(), "Pair should return the expected symbol")
|
||||
|
||||
@@ -28,41 +28,41 @@ type MarketSummary []*MarketPair
|
||||
|
||||
// MarketPair is a single pair in Market Summary
|
||||
type MarketPair struct {
|
||||
Symbol string `json:"symbol"`
|
||||
Last float64 `json:"last"`
|
||||
LowestAsk float64 `json:"lowestAsk"`
|
||||
HighestBid float64 `json:"highestBid"`
|
||||
PercentageChange float64 `json:"percentageChange"`
|
||||
Volume float64 `json:"volume"`
|
||||
High24Hr float64 `json:"high24Hr"`
|
||||
Low24Hr float64 `json:"low24Hr"`
|
||||
Base string `json:"base"`
|
||||
Quote string `json:"quote"`
|
||||
Active bool `json:"active"`
|
||||
Size float64 `json:"size"`
|
||||
MinValidPrice float64 `json:"minValidPrice"`
|
||||
MinPriceIncrement float64 `json:"minPriceIncrement"`
|
||||
MinOrderSize float64 `json:"minOrderSize"`
|
||||
MaxOrderSize float64 `json:"maxOrderSize"`
|
||||
MinSizeIncrement float64 `json:"minSizeIncrement"`
|
||||
OpenInterest float64 `json:"openInterest"`
|
||||
OpenInterestUSD float64 `json:"openInterestUSD"`
|
||||
ContractStart int64 `json:"contractStart"`
|
||||
ContractEnd int64 `json:"contractEnd"`
|
||||
TimeBasedContract bool `json:"timeBasedContract"`
|
||||
OpenTime types.Time `json:"openTime"`
|
||||
CloseTime types.Time `json:"closeTime"`
|
||||
StartMatching int64 `json:"startMatching"`
|
||||
InactiveTime types.Time `json:"inactiveTime"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
ContractSize float64 `json:"contractSize"`
|
||||
MaxPosition int64 `json:"maxPosition"`
|
||||
MinRiskLimit int `json:"minRiskLimit"`
|
||||
MaxRiskLimit int `json:"maxRiskLimit"`
|
||||
AvailableSettlement []string `json:"availableSettlement"`
|
||||
Futures bool `json:"futures"`
|
||||
IsMarketOpenToSpot bool `json:"isMarketOpenToSpot"`
|
||||
IsMarketOpenToOTC bool `json:"isMarketOpenToOtc"`
|
||||
Symbol string `json:"symbol"`
|
||||
Last float64 `json:"last"`
|
||||
LowestAsk float64 `json:"lowestAsk"`
|
||||
HighestBid float64 `json:"highestBid"`
|
||||
PercentageChange float64 `json:"percentageChange"`
|
||||
Volume float64 `json:"volume"`
|
||||
High24Hr float64 `json:"high24Hr"`
|
||||
Low24Hr float64 `json:"low24Hr"`
|
||||
Base currency.Code `json:"base"`
|
||||
Quote currency.Code `json:"quote"`
|
||||
Active bool `json:"active"`
|
||||
Size float64 `json:"size"`
|
||||
MinValidPrice float64 `json:"minValidPrice"`
|
||||
MinPriceIncrement float64 `json:"minPriceIncrement"`
|
||||
MinOrderSize float64 `json:"minOrderSize"`
|
||||
MaxOrderSize float64 `json:"maxOrderSize"`
|
||||
MinSizeIncrement float64 `json:"minSizeIncrement"`
|
||||
OpenInterest float64 `json:"openInterest"`
|
||||
OpenInterestUSD float64 `json:"openInterestUSD"`
|
||||
ContractStart int64 `json:"contractStart"`
|
||||
ContractEnd int64 `json:"contractEnd"`
|
||||
TimeBasedContract bool `json:"timeBasedContract"`
|
||||
OpenTime types.Time `json:"openTime"`
|
||||
CloseTime types.Time `json:"closeTime"`
|
||||
StartMatching int64 `json:"startMatching"`
|
||||
InactiveTime types.Time `json:"inactiveTime"`
|
||||
FundingRate float64 `json:"fundingRate"`
|
||||
ContractSize float64 `json:"contractSize"`
|
||||
MaxPosition int64 `json:"maxPosition"`
|
||||
MinRiskLimit int `json:"minRiskLimit"`
|
||||
MaxRiskLimit int `json:"maxRiskLimit"`
|
||||
AvailableSettlement currency.Currencies `json:"availableSettlement"`
|
||||
Futures bool `json:"futures"`
|
||||
IsMarketOpenToSpot bool `json:"isMarketOpenToSpot"`
|
||||
IsMarketOpenToOTC bool `json:"isMarketOpenToOtc"`
|
||||
}
|
||||
|
||||
// OHLCV holds Open, High Low, Close, Volume data for set symbol
|
||||
|
||||
@@ -996,27 +996,28 @@ func (m *MarketPair) StripExponent() (string, error) {
|
||||
// Pair returns the currency Pair for a MarketPair
|
||||
func (m *MarketPair) Pair() (currency.Pair, error) {
|
||||
baseCurr := m.Base
|
||||
var quoteCurr string
|
||||
var quoteStr string
|
||||
if m.Futures {
|
||||
if baseCurr == "TRUMPSOL" { // Only base currency which is different to the rest
|
||||
baseCurr = "TRUMP"
|
||||
quoteCurr = strings.TrimPrefix(m.Symbol, baseCurr)
|
||||
if baseCurr.String() == "TRUMPSOL" { // Only base currency which is different to the rest
|
||||
baseCurr = currency.TRUMP
|
||||
quoteStr = strings.TrimPrefix(m.Symbol, baseCurr.String())
|
||||
} else {
|
||||
s := strings.Split(m.Symbol, m.Base) // e.g. RUNEPFC for RUNE-USD futures pair
|
||||
// Quote field is the settlement currency, create the quote currency from the symbol
|
||||
s := strings.Split(m.Symbol, m.Base.String())
|
||||
if len(s) <= 1 {
|
||||
return currency.EMPTYPAIR, errInvalidPairSymbol
|
||||
}
|
||||
quoteCurr = s[1]
|
||||
quoteStr = s[1]
|
||||
}
|
||||
} else {
|
||||
s := strings.Split(m.Symbol, currency.DashDelimiter)
|
||||
if len(s) != 2 {
|
||||
return currency.EMPTYPAIR, errInvalidPairSymbol
|
||||
}
|
||||
baseCurr = s[0]
|
||||
quoteCurr = s[1]
|
||||
baseCurr = currency.NewCode(s[0])
|
||||
quoteStr = s[1]
|
||||
}
|
||||
return currency.NewPairFromStrings(baseCurr, quoteCurr)
|
||||
return currency.NewPair(baseCurr, currency.NewCode(quoteStr)), nil
|
||||
}
|
||||
|
||||
// GetMarketSummary returns filtered market pair details; Specifically:
|
||||
@@ -1055,9 +1056,6 @@ func (e *Exchange) GetMarketSummary(ctx context.Context, symbol string, spot boo
|
||||
|
||||
// GetFuturesContractDetails returns details about futures contracts
|
||||
func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Item) ([]futures.Contract, error) {
|
||||
if !item.IsFutures() {
|
||||
return nil, futures.ErrNotFuturesAsset
|
||||
}
|
||||
if item != asset.Futures {
|
||||
return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, item)
|
||||
}
|
||||
@@ -1065,67 +1063,46 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp := make([]futures.Contract, 0, len(marketSummary))
|
||||
resp := make([]futures.Contract, len(marketSummary))
|
||||
for i := range marketSummary {
|
||||
var cp currency.Pair
|
||||
cp, err = currency.NewPairFromStrings(marketSummary[i].Base, marketSummary[i].Symbol[len(marketSummary[i].Base):])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
settlementCurrencies := make(currency.Currencies, len(marketSummary[i].AvailableSettlement))
|
||||
var startTime, endTime time.Time
|
||||
var ct futures.ContractType
|
||||
if !marketSummary[i].OpenTime.Time().IsZero() {
|
||||
startTime = marketSummary[i].OpenTime.Time()
|
||||
}
|
||||
if !marketSummary[i].CloseTime.Time().IsZero() {
|
||||
endTime = marketSummary[i].CloseTime.Time()
|
||||
}
|
||||
// Quote field is the settlement currency, create the quote currency from the symbol
|
||||
quote := currency.NewCode(marketSummary[i].Symbol[len(marketSummary[i].Base.String()):])
|
||||
cp := currency.NewPair(marketSummary[i].Base, quote)
|
||||
startTime := marketSummary[i].OpenTime.Time()
|
||||
endTime := marketSummary[i].CloseTime.Time()
|
||||
ct := futures.Perpetual
|
||||
if marketSummary[i].TimeBasedContract {
|
||||
if endTime.Sub(startTime) > kline.OneMonth.Duration() {
|
||||
ct = futures.Quarterly
|
||||
} else {
|
||||
ct = futures.Monthly
|
||||
}
|
||||
} else {
|
||||
ct = futures.Perpetual
|
||||
}
|
||||
var contractSettlementType futures.ContractSettlementType
|
||||
for j := range marketSummary[i].AvailableSettlement {
|
||||
settlementCurrencies[j] = currency.NewCode(marketSummary[i].AvailableSettlement[j])
|
||||
if contractSettlementType == futures.LinearOrInverse {
|
||||
continue
|
||||
}
|
||||
containsUSD := strings.Contains(marketSummary[i].AvailableSettlement[j], "USD")
|
||||
if !containsUSD {
|
||||
contractSettlementType = futures.LinearOrInverse
|
||||
continue
|
||||
}
|
||||
if containsUSD {
|
||||
contractSettlementType = futures.Linear
|
||||
}
|
||||
}
|
||||
|
||||
c := futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: currency.NewPair(currency.NewCode(marketSummary[i].Base), currency.NewCode(marketSummary[i].Quote)),
|
||||
Asset: item,
|
||||
SettlementCurrencies: settlementCurrencies,
|
||||
StartDate: startTime,
|
||||
EndDate: endTime,
|
||||
SettlementType: contractSettlementType,
|
||||
IsActive: marketSummary[i].Active,
|
||||
Type: ct,
|
||||
contractSettlementType := futures.LinearOrInverse
|
||||
if marketSummary[i].AvailableSettlement.Contains(currency.USD) {
|
||||
contractSettlementType = futures.Linear
|
||||
}
|
||||
var rate fundingrate.Rate
|
||||
if marketSummary[i].FundingRate > 0 {
|
||||
c.LatestRate = fundingrate.Rate{
|
||||
rate = fundingrate.Rate{
|
||||
Rate: decimal.NewFromFloat(marketSummary[i].FundingRate),
|
||||
Time: time.Now().Truncate(time.Hour),
|
||||
}
|
||||
}
|
||||
|
||||
resp = append(resp, c)
|
||||
resp[i] = futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: currency.NewPair(marketSummary[i].Base, marketSummary[i].Quote),
|
||||
Asset: item,
|
||||
SettlementCurrency: currency.USDT,
|
||||
AdditionalSettlementCurrencies: marketSummary[i].AvailableSettlement,
|
||||
StartDate: startTime,
|
||||
EndDate: endTime,
|
||||
SettlementType: contractSettlementType,
|
||||
IsActive: marketSummary[i].Active,
|
||||
Type: ct,
|
||||
LatestRate: rate,
|
||||
}
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -97,9 +97,9 @@ type InstrumentInfo struct {
|
||||
MinNotionalValue types.Number `json:"minNotionalValue"`
|
||||
MaxMarketOrderQuantity types.Number `json:"maxMktOrderQty"`
|
||||
} `json:"lotSizeFilter"`
|
||||
UnifiedMarginTrade bool `json:"unifiedMarginTrade"`
|
||||
FundingInterval int64 `json:"fundingInterval"`
|
||||
SettleCoin string `json:"settleCoin"`
|
||||
UnifiedMarginTrade bool `json:"unifiedMarginTrade"`
|
||||
FundingInterval int64 `json:"fundingInterval"`
|
||||
SettleCoin currency.Code `json:"settleCoin"`
|
||||
}
|
||||
|
||||
// RestResponse represents a REST response instance.
|
||||
|
||||
@@ -1771,7 +1771,7 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
case asset.CoinMarginedFutures:
|
||||
resp := make([]futures.Contract, 0, len(inverseContracts.List))
|
||||
for i := range inverseContracts.List {
|
||||
if inverseContracts.List[i].SettleCoin == "USDT" || inverseContracts.List[i].SettleCoin == "USDC" {
|
||||
if inverseContracts.List[i].SettleCoin.Equal(currency.USDT) || inverseContracts.List[i].SettleCoin.Equal(currency.USDC) {
|
||||
continue
|
||||
}
|
||||
var cp, underlying currency.Pair
|
||||
@@ -1810,18 +1810,18 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
}
|
||||
|
||||
resp = append(resp, futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp.Format(format),
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: start,
|
||||
EndDate: end,
|
||||
SettlementType: futures.Inverse,
|
||||
IsActive: strings.EqualFold(inverseContracts.List[i].Status, "trading"),
|
||||
Status: inverseContracts.List[i].Status,
|
||||
Type: ct,
|
||||
SettlementCurrencies: currency.Currencies{currency.NewCode(inverseContracts.List[i].SettleCoin)},
|
||||
MaxLeverage: inverseContracts.List[i].LeverageFilter.MaxLeverage.Float64(),
|
||||
Exchange: e.Name,
|
||||
Name: cp.Format(format),
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: start,
|
||||
EndDate: end,
|
||||
SettlementType: futures.Inverse,
|
||||
IsActive: strings.EqualFold(inverseContracts.List[i].Status, "trading"),
|
||||
Status: inverseContracts.List[i].Status,
|
||||
Type: ct,
|
||||
SettlementCurrency: inverseContracts.List[i].SettleCoin,
|
||||
MaxLeverage: inverseContracts.List[i].LeverageFilter.MaxLeverage.Float64(),
|
||||
})
|
||||
}
|
||||
return resp, nil
|
||||
@@ -1834,13 +1834,13 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
|
||||
var instruments []*InstrumentInfo
|
||||
for i := range linearContracts.List {
|
||||
if linearContracts.List[i].SettleCoin != "USDC" {
|
||||
if !linearContracts.List[i].SettleCoin.Equal(currency.USDC) {
|
||||
continue
|
||||
}
|
||||
instruments = append(instruments, linearContracts.List[i])
|
||||
}
|
||||
for i := range inverseContracts.List {
|
||||
if inverseContracts.List[i].SettleCoin != "USDC" {
|
||||
if !inverseContracts.List[i].SettleCoin.Equal(currency.USDC) {
|
||||
continue
|
||||
}
|
||||
instruments = append(instruments, inverseContracts.List[i])
|
||||
@@ -1888,19 +1888,19 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
}
|
||||
|
||||
resp = append(resp, futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp.Format(format),
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: instruments[i].LaunchTime.Time(),
|
||||
EndDate: instruments[i].DeliveryTime.Time(),
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: strings.EqualFold(instruments[i].Status, "trading"),
|
||||
Status: instruments[i].Status,
|
||||
Type: ct,
|
||||
SettlementCurrencies: currency.Currencies{currency.USDC},
|
||||
MaxLeverage: instruments[i].LeverageFilter.MaxLeverage.Float64(),
|
||||
Multiplier: instruments[i].LeverageFilter.LeverageStep.Float64(),
|
||||
Exchange: e.Name,
|
||||
Name: cp.Format(format),
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: instruments[i].LaunchTime.Time(),
|
||||
EndDate: instruments[i].DeliveryTime.Time(),
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: strings.EqualFold(instruments[i].Status, "trading"),
|
||||
Status: instruments[i].Status,
|
||||
Type: ct,
|
||||
SettlementCurrency: currency.USDC,
|
||||
MaxLeverage: instruments[i].LeverageFilter.MaxLeverage.Float64(),
|
||||
Multiplier: instruments[i].LeverageFilter.LeverageStep.Float64(),
|
||||
})
|
||||
}
|
||||
return resp, nil
|
||||
@@ -1913,13 +1913,13 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
|
||||
var instruments []*InstrumentInfo
|
||||
for i := range linearContracts.List {
|
||||
if linearContracts.List[i].SettleCoin != "USDT" {
|
||||
if !linearContracts.List[i].SettleCoin.Equal(currency.USDT) {
|
||||
continue
|
||||
}
|
||||
instruments = append(instruments, linearContracts.List[i])
|
||||
}
|
||||
for i := range inverseContracts.List {
|
||||
if inverseContracts.List[i].SettleCoin != "USDT" {
|
||||
if !inverseContracts.List[i].SettleCoin.Equal(currency.USDT) {
|
||||
continue
|
||||
}
|
||||
instruments = append(instruments, inverseContracts.List[i])
|
||||
@@ -1961,19 +1961,19 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
}
|
||||
|
||||
resp = append(resp, futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp.Format(format),
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: start,
|
||||
EndDate: end,
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: strings.EqualFold(instruments[i].Status, "trading"),
|
||||
Status: instruments[i].Status,
|
||||
Type: ct,
|
||||
SettlementCurrencies: currency.Currencies{currency.USDT},
|
||||
MaxLeverage: instruments[i].LeverageFilter.MaxLeverage.Float64(),
|
||||
Multiplier: instruments[i].LeverageFilter.LeverageStep.Float64(),
|
||||
Exchange: e.Name,
|
||||
Name: cp.Format(format),
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: start,
|
||||
EndDate: end,
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: strings.EqualFold(instruments[i].Status, "trading"),
|
||||
Status: instruments[i].Status,
|
||||
Type: ct,
|
||||
SettlementCurrency: currency.USDT,
|
||||
MaxLeverage: instruments[i].LeverageFilter.MaxLeverage.Float64(),
|
||||
Multiplier: instruments[i].LeverageFilter.LeverageStep.Float64(),
|
||||
})
|
||||
}
|
||||
return resp, nil
|
||||
|
||||
@@ -873,15 +873,15 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
Rate: decimal.NewFromFloat(products.Products[i].FutureProductDetails.PerpetualDetails.FundingRate.Float64()),
|
||||
}
|
||||
contracts[i] = futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: products.Products[i].ID,
|
||||
Asset: item,
|
||||
EndDate: products.Products[i].FutureProductDetails.ContractExpiry,
|
||||
IsActive: !products.Products[i].IsDisabled,
|
||||
Status: products.Products[i].Status,
|
||||
SettlementCurrencies: currency.Currencies{products.Products[i].QuoteCurrencyID},
|
||||
Multiplier: products.Products[i].BaseIncrement.Float64(),
|
||||
LatestRate: funRate,
|
||||
Exchange: e.Name,
|
||||
Name: products.Products[i].ID,
|
||||
Asset: item,
|
||||
EndDate: products.Products[i].FutureProductDetails.ContractExpiry,
|
||||
IsActive: !products.Products[i].IsDisabled,
|
||||
Status: products.Products[i].Status,
|
||||
SettlementCurrency: products.Products[i].QuoteCurrencyID,
|
||||
Multiplier: products.Products[i].BaseIncrement.Float64(),
|
||||
LatestRate: funRate,
|
||||
}
|
||||
if i < perpStart {
|
||||
contracts[i].Type = futures.LongDated
|
||||
|
||||
@@ -192,31 +192,31 @@ type IndexPriceData struct {
|
||||
|
||||
// InstrumentData gets data for instruments
|
||||
type InstrumentData struct {
|
||||
InstrumentName string `json:"instrument_name"`
|
||||
BaseCurrency string `json:"base_currency"`
|
||||
Kind string `json:"kind"`
|
||||
OptionType string `json:"option_type"`
|
||||
QuoteCurrency string `json:"quote_currency"`
|
||||
BlockTradeCommission float64 `json:"block_trade_commission"`
|
||||
ContractSize float64 `json:"contract_size"`
|
||||
CreationTimestamp types.Time `json:"creation_timestamp"`
|
||||
ExpirationTimestamp types.Time `json:"expiration_timestamp"`
|
||||
IsActive bool `json:"is_active"`
|
||||
Leverage float64 `json:"leverage"`
|
||||
MaxLeverage float64 `json:"max_leverage"`
|
||||
MakerCommission float64 `json:"maker_commission"`
|
||||
MinimumTradeAmount float64 `json:"min_trade_amount"`
|
||||
TickSize float64 `json:"tick_size"`
|
||||
TakerCommission float64 `json:"taker_commission"`
|
||||
Strike float64 `json:"strike"`
|
||||
SettlementPeriod string `json:"settlement_period"`
|
||||
SettlementCurrency string `json:"settlement_currency"`
|
||||
RequestForQuote bool `json:"rfq"`
|
||||
PriceIndex string `json:"price_index"`
|
||||
InstrumentID int64 `json:"instrument_id"`
|
||||
CounterCurrency string `json:"counter_currency"`
|
||||
MaximumLiquidationCommission float64 `json:"max_liquidation_commission"`
|
||||
FutureType string `json:"future_type"`
|
||||
InstrumentName string `json:"instrument_name"`
|
||||
BaseCurrency currency.Code `json:"base_currency"`
|
||||
Kind string `json:"kind"`
|
||||
OptionType string `json:"option_type"`
|
||||
QuoteCurrency currency.Code `json:"quote_currency"`
|
||||
BlockTradeCommission float64 `json:"block_trade_commission"`
|
||||
ContractSize float64 `json:"contract_size"`
|
||||
CreationTimestamp types.Time `json:"creation_timestamp"`
|
||||
ExpirationTimestamp types.Time `json:"expiration_timestamp"`
|
||||
IsActive bool `json:"is_active"`
|
||||
Leverage float64 `json:"leverage"`
|
||||
MaxLeverage float64 `json:"max_leverage"`
|
||||
MakerCommission float64 `json:"maker_commission"`
|
||||
MinimumTradeAmount float64 `json:"min_trade_amount"`
|
||||
TickSize float64 `json:"tick_size"`
|
||||
TakerCommission float64 `json:"taker_commission"`
|
||||
Strike float64 `json:"strike"`
|
||||
SettlementPeriod string `json:"settlement_period"`
|
||||
SettlementCurrency currency.Code `json:"settlement_currency"`
|
||||
RequestForQuote bool `json:"rfq"`
|
||||
PriceIndex string `json:"price_index"`
|
||||
InstrumentID int64 `json:"instrument_id"`
|
||||
CounterCurrency string `json:"counter_currency"`
|
||||
MaximumLiquidationCommission float64 `json:"max_liquidation_commission"`
|
||||
FutureType string `json:"future_type"`
|
||||
TickSizeSteps []struct {
|
||||
AbovePrice float64 `json:"above_price"`
|
||||
TickSize float64 `json:"tick_size"`
|
||||
|
||||
@@ -1177,18 +1177,18 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
contractSettlementType = futures.Linear
|
||||
}
|
||||
resp = append(resp, futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: currency.NewPair(currency.NewCode(inst.BaseCurrency), currency.NewCode(inst.QuoteCurrency)),
|
||||
Asset: item,
|
||||
SettlementCurrencies: []currency.Code{currency.NewCode(inst.SettlementCurrency)},
|
||||
StartDate: inst.CreationTimestamp.Time(),
|
||||
EndDate: inst.ExpirationTimestamp.Time(),
|
||||
Type: ct,
|
||||
SettlementType: contractSettlementType,
|
||||
IsActive: inst.IsActive,
|
||||
MaxLeverage: inst.MaxLeverage,
|
||||
Multiplier: inst.ContractSize,
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: currency.NewPair(inst.BaseCurrency, inst.QuoteCurrency),
|
||||
Asset: item,
|
||||
SettlementCurrency: inst.SettlementCurrency,
|
||||
StartDate: inst.CreationTimestamp.Time(),
|
||||
EndDate: inst.ExpirationTimestamp.Time(),
|
||||
Type: ct,
|
||||
SettlementType: contractSettlementType,
|
||||
IsActive: inst.IsActive,
|
||||
MaxLeverage: inst.MaxLeverage,
|
||||
Multiplier: inst.ContractSize,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,13 +30,14 @@ type Contract struct {
|
||||
Type ContractType
|
||||
SettlementType ContractSettlementType
|
||||
// Optional values if the exchange offers them
|
||||
SettlementCurrencies currency.Currencies
|
||||
MarginCurrency currency.Code
|
||||
Multiplier float64
|
||||
MaxLeverage float64
|
||||
LatestRate fundingrate.Rate
|
||||
FundingRateFloor decimal.Decimal
|
||||
FundingRateCeiling decimal.Decimal
|
||||
SettlementCurrency currency.Code
|
||||
AdditionalSettlementCurrencies currency.Currencies
|
||||
MarginCurrency currency.Code
|
||||
Multiplier float64
|
||||
MaxLeverage float64
|
||||
LatestRate fundingrate.Rate
|
||||
FundingRateFloor decimal.Decimal
|
||||
FundingRateCeiling decimal.Decimal
|
||||
}
|
||||
|
||||
// ContractSettlementType holds the various style of contracts offered by futures exchanges
|
||||
|
||||
@@ -1781,16 +1781,16 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, a asset.Item)
|
||||
contractSettlementType = futures.Quanto
|
||||
}
|
||||
c := futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: contracts[i].Name,
|
||||
Underlying: contracts[i].Name,
|
||||
Asset: a,
|
||||
IsActive: contracts[i].DelistedTime.Time().IsZero() || contracts[i].DelistedTime.Time().After(time.Now()),
|
||||
Type: futures.Perpetual,
|
||||
SettlementType: contractSettlementType,
|
||||
SettlementCurrencies: currency.Currencies{settle},
|
||||
Multiplier: contracts[i].QuantoMultiplier.Float64(),
|
||||
MaxLeverage: contracts[i].LeverageMax.Float64(),
|
||||
Exchange: e.Name,
|
||||
Name: contracts[i].Name,
|
||||
Underlying: contracts[i].Name,
|
||||
Asset: a,
|
||||
IsActive: contracts[i].DelistedTime.Time().IsZero() || contracts[i].DelistedTime.Time().After(time.Now()),
|
||||
Type: futures.Perpetual,
|
||||
SettlementType: contractSettlementType,
|
||||
SettlementCurrency: settle,
|
||||
Multiplier: contracts[i].QuantoMultiplier.Float64(),
|
||||
MaxLeverage: contracts[i].LeverageMax.Float64(),
|
||||
}
|
||||
c.LatestRate = fundingrate.Rate{
|
||||
Time: contracts[i].FundingNextApply.Time().Add(-time.Duration(contracts[i].FundingInterval) * time.Second),
|
||||
@@ -1834,19 +1834,18 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, a asset.Item)
|
||||
startTime = endTime.Add(-kline.SixMonth.Duration())
|
||||
}
|
||||
resp[i] = futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: name,
|
||||
Underlying: underlying,
|
||||
Asset: a,
|
||||
StartDate: startTime,
|
||||
EndDate: endTime,
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: !contracts[i].InDelisting,
|
||||
Type: ct,
|
||||
SettlementCurrencies: currency.Currencies{settle},
|
||||
MarginCurrency: currency.Code{},
|
||||
Multiplier: contracts[i].QuantoMultiplier.Float64(),
|
||||
MaxLeverage: contracts[i].LeverageMax.Float64(),
|
||||
Exchange: e.Name,
|
||||
Name: name,
|
||||
Underlying: underlying,
|
||||
Asset: a,
|
||||
StartDate: startTime,
|
||||
EndDate: endTime,
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: !contracts[i].InDelisting,
|
||||
Type: ct,
|
||||
SettlementCurrency: settle,
|
||||
Multiplier: contracts[i].QuantoMultiplier.Float64(),
|
||||
MaxLeverage: contracts[i].LeverageMax.Float64(),
|
||||
}
|
||||
}
|
||||
return resp, nil
|
||||
|
||||
@@ -2009,16 +2009,16 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
}
|
||||
|
||||
resp = append(resp, futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: s,
|
||||
SettlementType: futures.Inverse,
|
||||
IsActive: result[x].ContractStatus == 1,
|
||||
Type: futures.Perpetual,
|
||||
SettlementCurrencies: currency.Currencies{currency.USD},
|
||||
Multiplier: result[x].ContractSize,
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: s,
|
||||
SettlementType: futures.Inverse,
|
||||
IsActive: result[x].ContractStatus == 1,
|
||||
Type: futures.Perpetual,
|
||||
SettlementCurrency: currency.USD,
|
||||
Multiplier: result[x].ContractSize,
|
||||
})
|
||||
}
|
||||
return resp, nil
|
||||
@@ -2065,17 +2065,17 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
}
|
||||
|
||||
resp = append(resp, futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: startTime,
|
||||
EndDate: endTime,
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: result.Data[x].ContractStatus == 1,
|
||||
Type: ct,
|
||||
SettlementCurrencies: currency.Currencies{currency.USD},
|
||||
Multiplier: result.Data[x].ContractSize,
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: underlying,
|
||||
Asset: item,
|
||||
StartDate: startTime,
|
||||
EndDate: endTime,
|
||||
SettlementType: futures.Linear,
|
||||
IsActive: result.Data[x].ContractStatus == 1,
|
||||
Type: ct,
|
||||
SettlementCurrency: currency.USD,
|
||||
Multiplier: result.Data[x].ContractSize,
|
||||
})
|
||||
}
|
||||
return resp, nil
|
||||
|
||||
@@ -1897,19 +1897,19 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
}
|
||||
timeOfCurrentFundingRate := time.Now().Add((time.Duration(contracts[i].NextFundingRateTime) * time.Millisecond) - fri).Truncate(time.Hour).UTC()
|
||||
resp[i] = futures.Contract{
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: underlying,
|
||||
SettlementCurrencies: currency.Currencies{settleCurr},
|
||||
MarginCurrency: settleCurr,
|
||||
Asset: item,
|
||||
StartDate: contracts[i].FirstOpenDate.Time(),
|
||||
EndDate: contracts[i].ExpireDate.Time(),
|
||||
IsActive: !strings.EqualFold(contracts[i].Status, "closed"),
|
||||
Status: contracts[i].Status,
|
||||
Multiplier: contracts[i].Multiplier,
|
||||
MaxLeverage: contracts[i].MaxLeverage,
|
||||
SettlementType: contractSettlementType,
|
||||
Exchange: e.Name,
|
||||
Name: cp,
|
||||
Underlying: underlying,
|
||||
SettlementCurrency: settleCurr,
|
||||
MarginCurrency: settleCurr,
|
||||
Asset: item,
|
||||
StartDate: contracts[i].FirstOpenDate.Time(),
|
||||
EndDate: contracts[i].ExpireDate.Time(),
|
||||
IsActive: !strings.EqualFold(contracts[i].Status, "closed"),
|
||||
Status: contracts[i].Status,
|
||||
Multiplier: contracts[i].Multiplier,
|
||||
MaxLeverage: contracts[i].MaxLeverage,
|
||||
SettlementType: contractSettlementType,
|
||||
LatestRate: fundingrate.Rate{
|
||||
Rate: decimal.NewFromFloat(contracts[i].FundingFeeRate),
|
||||
Time: timeOfCurrentFundingRate, // kucoin pays every 8 hours
|
||||
|
||||
@@ -2814,7 +2814,7 @@ func (e *Exchange) GetFuturesContractDetails(ctx context.Context, item asset.Ite
|
||||
}
|
||||
|
||||
if !settleCurr.IsEmpty() {
|
||||
resp[i].SettlementCurrencies = currency.Currencies{settleCurr}
|
||||
resp[i].SettlementCurrency = settleCurr
|
||||
}
|
||||
}
|
||||
return resp, nil
|
||||
|
||||
Reference in New Issue
Block a user