mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-05 07:26:47 +00:00
exchange: upgrade UpdatePair method (#991)
* exchange: upgrade update pair * exchanges: Add enabled string matching and format handling if discrepency is found. * linter: fixes * bithumb: fix tests * BTSE: api change fix ordering * huobi: fix tests * gloriousnits: stage 1 * gloriousnits: stage 2 * currency: more nits * bitmex: add spot and process pairs before currency package call. * bitmex: finished correct orderbook matching and other implementations * linter: fix issue * currency: Fix linter * currency: segregate and protect pair store, update tests * currency/manager: clean code, rm log output * currency: Add store method and make sure formatting stays nil if not stored. * gct: check errors * engine/websocketroutineman: fix tests * bybit: fix duplication bug * huobi: fix test * btse: fix tests? * ob/buffer: fix tests * Update currency/manager.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * glorious: nits strikes again. * exchange: add bypassConfigFormatUpgrades to stop formatting * GLORIOUS LINTER * Update exchanges/bithumb/bithumb_wrapper.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * exchange: fix pair upgrade issue when duplications are in both avail and enabled pairs * linter: fix shadow dec * config: fix test * Update currency/pair_test.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Scott <gloriousCode@users.noreply.github.com>
This commit is contained in:
@@ -103,6 +103,14 @@ const (
|
||||
ContractDownsideProfit
|
||||
// ContractUpsideProfit upside profit contract type
|
||||
ContractUpsideProfit
|
||||
|
||||
perpetualContractID = "FFWCSX"
|
||||
spotID = "IFXXXP"
|
||||
futuresID = "FFCCSX"
|
||||
bitMEXBasketIndexID = "MRBXXX"
|
||||
bitMEXPriceIndexID = "MRCXXX"
|
||||
bitMEXLendingPremiumIndexID = "MRRXXX"
|
||||
bitMEXVolatilityIndexID = "MRIXXX"
|
||||
)
|
||||
|
||||
// GetAnnouncement returns the general announcements from Bitmex
|
||||
|
||||
@@ -3,7 +3,6 @@ package bitmex
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
)
|
||||
|
||||
@@ -122,107 +121,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 string `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 int64 `json:"lotSize"`
|
||||
LowPrice float64 `json:"lowPrice"`
|
||||
MaintMargin float64 `json:"maintMargin"`
|
||||
MakerFee float64 `json:"makerFee"`
|
||||
MarkMethod string `json:"markMethod"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
MaxOrderQty int64 `json:"maxOrderQty"`
|
||||
MaxPrice float64 `json:"maxPrice"`
|
||||
MidPrice float64 `json:"midPrice"`
|
||||
Multiplier int64 `json:"multiplier"`
|
||||
OpenInterest int64 `json:"openInterest"`
|
||||
OpenValue int64 `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 int64 `json:"prevTotalTurnover"`
|
||||
PrevTotalVolume int64 `json:"prevTotalVolume"`
|
||||
PublishInterval string `json:"publishInterval"`
|
||||
PublishTime string `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 int64 `json:"riskLimit"`
|
||||
RiskStep int64 `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 currency.Pair `json:"symbol"`
|
||||
TakerFee float64 `json:"takerFee"`
|
||||
Taxed bool `json:"taxed"`
|
||||
TickSize float64 `json:"tickSize"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
TotalTurnover int64 `json:"totalTurnover"`
|
||||
TotalVolume int64 `json:"totalVolume"`
|
||||
Turnover int64 `json:"turnover"`
|
||||
Turnover24h int64 `json:"turnover24h"`
|
||||
Typ string `json:"typ"`
|
||||
Underlying string `json:"underlying"`
|
||||
UnderlyingSymbol string `json:"underlyingSymbol"`
|
||||
UnderlyingToPositionMultiplier int64 `json:"underlyingToPositionMultiplier"`
|
||||
UnderlyingToSettleMultiplier int64 `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 string `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 int64 `json:"lotSize"`
|
||||
LowPrice float64 `json:"lowPrice"`
|
||||
MaintMargin float64 `json:"maintMargin"`
|
||||
MakerFee float64 `json:"makerFee"`
|
||||
MarkMethod string `json:"markMethod"`
|
||||
MarkPrice float64 `json:"markPrice"`
|
||||
MaxOrderQty int64 `json:"maxOrderQty"`
|
||||
MaxPrice float64 `json:"maxPrice"`
|
||||
MidPrice float64 `json:"midPrice"`
|
||||
Multiplier int64 `json:"multiplier"`
|
||||
OpenInterest int64 `json:"openInterest"`
|
||||
OpenValue int64 `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 int64 `json:"prevTotalTurnover"`
|
||||
PrevTotalVolume int64 `json:"prevTotalVolume"`
|
||||
PublishInterval string `json:"publishInterval"`
|
||||
PublishTime string `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 int64 `json:"riskLimit"`
|
||||
RiskStep int64 `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 int64 `json:"totalTurnover"`
|
||||
TotalVolume int64 `json:"totalVolume"`
|
||||
Turnover int64 `json:"turnover"`
|
||||
Turnover24h int64 `json:"turnover24h"`
|
||||
Typ string `json:"typ"`
|
||||
Underlying string `json:"underlying"`
|
||||
UnderlyingSymbol string `json:"underlyingSymbol"`
|
||||
UnderlyingToPositionMultiplier int64 `json:"underlyingToPositionMultiplier"`
|
||||
UnderlyingToSettleMultiplier int64 `json:"underlyingToSettleMultiplier"`
|
||||
Volume float64 `json:"volume"`
|
||||
Volume24h float64 `json:"volume24h"`
|
||||
Vwap float64 `json:"vwap"`
|
||||
}
|
||||
|
||||
// InstrumentInterval instrument interval
|
||||
|
||||
@@ -186,26 +186,18 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error {
|
||||
if len(orderbooks.Data) == 0 {
|
||||
return fmt.Errorf("%s - Empty orderbook data received: %s", b.Name, respRaw)
|
||||
}
|
||||
var p currency.Pair
|
||||
p, err = currency.NewPairFromString(orderbooks.Data[0].Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var pair currency.Pair
|
||||
var a asset.Item
|
||||
a, err = b.GetPairAssetType(p)
|
||||
pair, a, err = b.GetPairAndAssetTypeRequestFormatted(orderbooks.Data[0].Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = b.processOrderbook(orderbooks.Data,
|
||||
orderbooks.Action,
|
||||
p,
|
||||
a)
|
||||
err = b.processOrderbook(orderbooks.Data, orderbooks.Action, pair, a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case bitmexWSTrade:
|
||||
if !b.IsSaveTradeDataEnabled() {
|
||||
return nil
|
||||
@@ -223,13 +215,8 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error {
|
||||
continue
|
||||
}
|
||||
var p currency.Pair
|
||||
p, err = currency.NewPairFromString(tradeHolder.Data[i].Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var a asset.Item
|
||||
a, err = b.GetPairAssetType(p)
|
||||
p, a, err = b.GetPairAndAssetTypeRequestFormatted(tradeHolder.Data[i].Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -285,13 +272,8 @@ func (b *Bitmex) wsHandleData(respRaw []byte) error {
|
||||
|
||||
for i := range response.Data {
|
||||
var p currency.Pair
|
||||
p, err = currency.NewPairFromString(response.Data[i].Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var a asset.Item
|
||||
a, err = b.GetPairAssetType(p)
|
||||
p, a, err = b.GetPairAndAssetTypeRequestFormatted(response.Data[i].Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -570,6 +552,10 @@ func (b *Bitmex) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, e
|
||||
|
||||
assets := b.GetAssetTypes(true)
|
||||
for x := range assets {
|
||||
pFmt, err := b.GetPairFormat(assets[x], true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
contracts, err := b.GetEnabledPairs(assets[x])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -581,7 +567,7 @@ func (b *Bitmex) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, e
|
||||
continue
|
||||
}
|
||||
subscriptions = append(subscriptions, stream.ChannelSubscription{
|
||||
Channel: channels[z] + ":" + contracts[y].String(),
|
||||
Channel: channels[z] + ":" + pFmt.Format(contracts[y]),
|
||||
Currency: contracts[y],
|
||||
Asset: assets[x],
|
||||
})
|
||||
@@ -596,6 +582,11 @@ func (b *Bitmex) GenerateAuthenticatedSubscriptions() ([]stream.ChannelSubscript
|
||||
if !b.Websocket.CanUseAuthenticatedEndpoints() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
pFmt, err := b.GetPairFormat(asset.PerpetualContract, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
contracts, err := b.GetEnabledPairs(asset.PerpetualContract)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -626,7 +617,7 @@ func (b *Bitmex) GenerateAuthenticatedSubscriptions() ([]stream.ChannelSubscript
|
||||
for i := range channels {
|
||||
for j := range contracts {
|
||||
subscriptions = append(subscriptions, stream.ChannelSubscription{
|
||||
Channel: channels[i] + ":" + contracts[j].String(),
|
||||
Channel: channels[i] + ":" + pFmt.Format(contracts[j]),
|
||||
Currency: contracts[j],
|
||||
Asset: asset.PerpetualContract,
|
||||
})
|
||||
@@ -639,7 +630,6 @@ func (b *Bitmex) GenerateAuthenticatedSubscriptions() ([]stream.ChannelSubscript
|
||||
func (b *Bitmex) Subscribe(channelsToSubscribe []stream.ChannelSubscription) error {
|
||||
var subscriber WebsocketRequest
|
||||
subscriber.Command = "subscribe"
|
||||
|
||||
for i := range channelsToSubscribe {
|
||||
subscriber.Arguments = append(subscriber.Arguments,
|
||||
channelsToSubscribe[i].Channel)
|
||||
|
||||
@@ -62,13 +62,30 @@ func (b *Bitmex) SetDefaults() {
|
||||
b.API.CredentialsValidator.RequiresKey = true
|
||||
b.API.CredentialsValidator.RequiresSecret = true
|
||||
|
||||
requestFmt := ¤cy.PairFormat{Uppercase: true}
|
||||
configFmt := ¤cy.PairFormat{Uppercase: true}
|
||||
err := b.SetGlobalPairsManager(requestFmt,
|
||||
configFmt,
|
||||
asset.PerpetualContract,
|
||||
asset.Futures,
|
||||
asset.Index)
|
||||
configFmt := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.DashDelimiter}
|
||||
standardRequestFmt := ¤cy.PairFormat{Uppercase: true}
|
||||
spotRequestFormat := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.UnderscoreDelimiter}
|
||||
|
||||
spot := currency.PairStore{RequestFormat: spotRequestFormat, ConfigFormat: configFmt}
|
||||
err := b.StoreAssetPairFormat(asset.Spot, spot)
|
||||
if err != nil {
|
||||
log.Errorln(log.ExchangeSys, err)
|
||||
}
|
||||
|
||||
perp := currency.PairStore{RequestFormat: standardRequestFmt, ConfigFormat: configFmt}
|
||||
err = b.StoreAssetPairFormat(asset.PerpetualContract, perp)
|
||||
if err != nil {
|
||||
log.Errorln(log.ExchangeSys, err)
|
||||
}
|
||||
|
||||
futures := currency.PairStore{RequestFormat: standardRequestFmt, ConfigFormat: configFmt}
|
||||
err = b.StoreAssetPairFormat(asset.Futures, futures)
|
||||
if err != nil {
|
||||
log.Errorln(log.ExchangeSys, err)
|
||||
}
|
||||
|
||||
index := currency.PairStore{RequestFormat: standardRequestFmt, ConfigFormat: configFmt}
|
||||
err = b.StoreAssetPairFormat(asset.Index, index)
|
||||
if err != nil {
|
||||
log.Errorln(log.ExchangeSys, err)
|
||||
}
|
||||
@@ -227,66 +244,99 @@ func (b *Bitmex) Run() {
|
||||
}
|
||||
|
||||
// FetchTradablePairs returns a list of the exchanges tradable pairs
|
||||
func (b *Bitmex) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) {
|
||||
func (b *Bitmex) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) {
|
||||
marketInfo, err := b.GetActiveAndIndexInstruments(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
products := make([]string, len(marketInfo))
|
||||
products := make([]string, 0, len(marketInfo))
|
||||
for x := range marketInfo {
|
||||
products[x] = marketInfo[x].Symbol.String()
|
||||
}
|
||||
if marketInfo[x].State != "Open" && a != asset.Index {
|
||||
continue
|
||||
}
|
||||
|
||||
switch a {
|
||||
case asset.Spot:
|
||||
if marketInfo[x].Typ == spotID {
|
||||
products = append(products, marketInfo[x].Symbol)
|
||||
}
|
||||
case asset.PerpetualContract:
|
||||
if marketInfo[x].Typ == perpetualContractID {
|
||||
var settleTrail string
|
||||
if strings.Contains(marketInfo[x].Symbol, currency.UnderscoreDelimiter) {
|
||||
// Example: ETHUSD_ETH quoted in USD, paid out in ETH.
|
||||
settlement := strings.Split(marketInfo[x].Symbol, currency.UnderscoreDelimiter)
|
||||
if len(settlement) != 2 {
|
||||
log.Warnf(log.ExchangeSys, "%s currency %s %s cannot be added to tradable pairs",
|
||||
b.Name,
|
||||
marketInfo[x].Symbol,
|
||||
a)
|
||||
break
|
||||
}
|
||||
settleTrail = currency.UnderscoreDelimiter + settlement[1]
|
||||
}
|
||||
products = append(products, marketInfo[x].Underlying+
|
||||
currency.DashDelimiter+
|
||||
marketInfo[x].QuoteCurrency+settleTrail)
|
||||
}
|
||||
case asset.Futures:
|
||||
if marketInfo[x].Typ == futuresID {
|
||||
isolate := strings.Split(marketInfo[x].Symbol, currency.UnderscoreDelimiter)
|
||||
if len(isolate[0]) < 3 {
|
||||
log.Warnf(log.ExchangeSys, "%s currency %s %s be cannot added to tradable pairs",
|
||||
b.Name,
|
||||
marketInfo[x].Symbol,
|
||||
a)
|
||||
break
|
||||
}
|
||||
var settleTrail string
|
||||
if len(isolate) == 2 {
|
||||
// Example: ETHUSDU22_ETH quoted in USD, paid out in ETH.
|
||||
settleTrail = currency.UnderscoreDelimiter + isolate[1]
|
||||
}
|
||||
|
||||
root := isolate[0][:len(isolate[0])-3]
|
||||
contract := isolate[0][len(isolate[0])-3:]
|
||||
|
||||
products = append(products, root+currency.DashDelimiter+contract+settleTrail)
|
||||
}
|
||||
case asset.Index:
|
||||
// TODO: This can be expanded into individual assets later.
|
||||
if marketInfo[x].Typ == bitMEXBasketIndexID ||
|
||||
marketInfo[x].Typ == bitMEXPriceIndexID ||
|
||||
marketInfo[x].Typ == bitMEXLendingPremiumIndexID ||
|
||||
marketInfo[x].Typ == bitMEXVolatilityIndexID {
|
||||
products = append(products, marketInfo[x].Symbol)
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("unhandled asset type")
|
||||
}
|
||||
}
|
||||
return products, nil
|
||||
}
|
||||
|
||||
// UpdateTradablePairs updates the exchanges available pairs and stores
|
||||
// them in the exchanges config
|
||||
func (b *Bitmex) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error {
|
||||
pairs, err := b.FetchTradablePairs(ctx, asset.Spot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
assets := b.GetAssetTypes(false)
|
||||
|
||||
// Zerovalue current list which will remove old asset pairs when contract
|
||||
// types expire or become obsolete
|
||||
var assetPairs = map[asset.Item][]string{
|
||||
asset.Index: {},
|
||||
asset.PerpetualContract: {},
|
||||
asset.Futures: {},
|
||||
}
|
||||
|
||||
for x := range pairs {
|
||||
if strings.Contains(pairs[x], ".") {
|
||||
assetPairs[asset.Index] = append(assetPairs[asset.Index], pairs[x])
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.Contains(pairs[x], "USD") {
|
||||
assetPairs[asset.PerpetualContract] = append(assetPairs[asset.PerpetualContract],
|
||||
pairs[x])
|
||||
continue
|
||||
}
|
||||
|
||||
assetPairs[asset.Futures] = append(assetPairs[asset.Futures], pairs[x])
|
||||
}
|
||||
|
||||
for a, values := range assetPairs {
|
||||
p, err := currency.NewPairsFromStrings(values)
|
||||
for x := range assets {
|
||||
pairsStr, err := b.FetchTradablePairs(ctx, assets[x])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = b.UpdatePairs(p, a, false, false)
|
||||
pairs, err := currency.NewPairsFromStrings(pairsStr)
|
||||
if err != nil {
|
||||
log.Warnf(log.ExchangeSys,
|
||||
"%s failed to update available pairs. Err: %v",
|
||||
b.Name,
|
||||
err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = b.UpdatePairs(pairs, assets[x], false, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -303,7 +353,13 @@ func (b *Bitmex) UpdateTickers(ctx context.Context, a asset.Item) error {
|
||||
}
|
||||
|
||||
for j := range tick {
|
||||
if !pairs.Contains(tick[j].Symbol, true) {
|
||||
var pair currency.Pair
|
||||
pair, err = currency.NewPairFromString(tick[j].Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !pairs.Contains(pair, true) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -315,7 +371,7 @@ func (b *Bitmex) UpdateTickers(ctx context.Context, a asset.Item) error {
|
||||
Ask: tick[j].AskPrice,
|
||||
Volume: tick[j].Volume24h,
|
||||
Close: tick[j].PrevClosePrice,
|
||||
Pair: tick[j].Symbol,
|
||||
Pair: pair,
|
||||
LastUpdated: tick[j].Timestamp,
|
||||
ExchangeName: b.Name,
|
||||
AssetType: a})
|
||||
|
||||
Reference in New Issue
Block a user