Skip to content

Commit

Permalink
Bitget interim commit
Browse files Browse the repository at this point in the history
  • Loading branch information
cranktakular committed Oct 16, 2024
1 parent 8114fae commit 5583f09
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 47 deletions.
5 changes: 5 additions & 0 deletions engine/websocketroutine_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
"github.com/thrasher-corp/gocryptotrader/exchanges/fill"
"github.com/thrasher-corp/gocryptotrader/exchanges/futures"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
Expand Down Expand Up @@ -373,6 +374,10 @@ func (m *WebsocketRoutineManager) websocketDataHandler(exchName string, data int
if m.verbose {
log.Infof(log.Fill, "%+v", d)
}
case []futures.PositionHistory:
if m.verbose {
log.Infof(log.Trade, "%+v", d)
}
default:
if m.verbose {
log.Warnf(log.WebsocketMgr,
Expand Down
76 changes: 46 additions & 30 deletions exchanges/bitget/bitget_websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/fill"
"github.com/thrasher-corp/gocryptotrader/exchanges/futures"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
Expand Down Expand Up @@ -605,31 +606,59 @@ func (bi *Bitget) wsHandleData(respRaw []byte) error {
if err != nil {
return err
}
resp := make([]order.Detail, len(positions))
resp := make([]futures.PositionHistory, len(positions))
for i := range positions {
pair, err := pairFromStringHelper(positions[i].InstrumentID)
if err != nil {
return err
}
resp[i] = order.Detail{
Exchange: bi.Name,
AssetType: asset.Futures,
Pair: pair,
OrderID: strconv.FormatInt(positions[i].PositionID, 10),
MarginType: marginDecoder(positions[i].MarginMode),
Side: sideDecoder(positions[i].HoldSide),
AverageExecutedPrice: positions[i].OpenPriceAverage,
Date: positions[i].CreationTime.Time(),
LastUpdated: positions[i].UpdateTime.Time(),
resp[i] = futures.PositionHistory{
Exchange: bi.Name,
PositionID: strconv.FormatInt(positions[i].PositionID, 10),
Pair: pair,
MarginCoin: currency.NewCode(positions[i].MarginCoin),
MarginType: marginDecoder(positions[i].MarginMode),
Side: sideDecoder(positions[i].HoldSide),
PositionMode: positionModeDecoder(positions[i].PositionMode),
OpenAveragePrice: positions[i].OpenPriceAverage,
CloseAveragePrice: positions[i].ClosePriceAverage,
OpenSize: positions[i].OpenSize,
CloseSize: positions[i].CloseSize,
RealisedPnl: positions[i].AchievedProfits,
SettlementFee: positions[i].SettleFee,
OpenFee: positions[i].OpenFee,
CloseFee: positions[i].CloseFee,
StartDate: positions[i].CreationTime.Time(),
LastUpdated: positions[i].UpdateTime.Time(),
}
}
// Implement a better handler for this once work on account.Holdings begins
bi.Websocket.DataHandler <- resp
case bitgetIndexPriceChannel:
// var indexPrice []WsIndexPriceResponse
// err := json.Unmarshal(wsResponse.Data, &indexPrice)
// if err != nil {
// return err
// }
var indexPrice []WsIndexPriceResponse
err := json.Unmarshal(wsResponse.Data, &indexPrice)
if err != nil {
return err
}
resp := make([]ticker.Price, len(indexPrice))
var cur int
for i := range indexPrice {
as := itemDecoder(wsResponse.Arg.InstrumentType)
pair, enabled, err := bi.MatchSymbolCheckEnabled(indexPrice[i].Symbol, as, false)
// The exchange sometimes returns unavailable pairs such as "USDT/USDT" which should be ignored
if !enabled || err != nil {
continue
}
resp[cur] = ticker.Price{
ExchangeName: bi.Name,
AssetType: as,
Pair: pair,
Last: indexPrice[i].IndexPrice,
LastUpdated: indexPrice[i].Timestamp.Time(),
}
}
resp = resp[:cur]
bi.Websocket.DataHandler <- resp
default:
bi.Websocket.DataHandler <- stream.UnhandledMessageWarning{Message: bi.Name + stream.UnhandledMessage + string(respRaw)}
}
Expand Down Expand Up @@ -882,7 +911,7 @@ func (bi *Bitget) generateDefaultSubscriptions() (subscription.List, error) {
for i := range subs {
subs[i].Channel = subscriptionNames[subs[i].Asset][subs[i].Channel]
switch subs[i].Channel {
case bitgetAccount, bitgetFillChannel, bitgetPositionsChannel, bitgetPositionsHistoryChannel:
case bitgetAccount, bitgetFillChannel, bitgetPositionsChannel, bitgetPositionsHistoryChannel, bitgetIndexPriceChannel:
default:
subs[i].Pairs = enabledPairs
}
Expand Down Expand Up @@ -1002,19 +1031,6 @@ func (bi *Bitget) websocketMessage(subs subscription.List, op string) error {
return errs
}

// itemEncoder encodes an asset.Item into a string
func itemEncoder(a asset.Item, pair currency.Pair) string {
switch a {
case asset.Spot:
return "SPOT"
case asset.Futures:
return getProductType(pair)
case asset.Margin, asset.CrossMargin:
return "MARGIN"
}
return ""
}

// GetSubscriptionTemplate returns a subscription channel template
func (bi *Bitget) GetSubscriptionTemplate(_ *subscription.Subscription) (*template.Template, error) {
return template.New("master.tmpl").Funcs(template.FuncMap{"channelName": channelName}).Parse(subTplText)
Expand Down
43 changes: 27 additions & 16 deletions exchanges/bitget/bitget_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,22 +237,9 @@ func (bi *Bitget) FetchTradablePairs(ctx context.Context, a asset.Item) (currenc
return nil, err
}
pairs := make(currency.Pairs, len(resp))
var cur int
for x := range resp {
if a == asset.Margin && resp[x].MaxIsolatedLeverage == 0 {
continue
}
if a == asset.CrossMargin && resp[x].MaxCrossedLeverage == 0 {
continue
}
pair, err := currency.NewPairFromString(resp[x].BaseCoin + "-" + resp[x].QuoteCoin)
if err != nil {
return nil, err
}
pairs[cur] = pair
cur++
pairs[x] = currency.NewPair(currency.NewCode(resp[x].BaseCoin), currency.NewCode(resp[x].QuoteCoin))
}
pairs = pairs[:cur]
return pairs, nil
}
return nil, asset.ErrNotSupported
Expand All @@ -261,7 +248,7 @@ func (bi *Bitget) FetchTradablePairs(ctx context.Context, a asset.Item) (currenc
// UpdateTradablePairs updates the exchanges available pairs and stores
// them in the exchanges config
func (bi *Bitget) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error {
assetTypes := bi.GetAssetTypes(true)
assetTypes := bi.GetAssetTypes(false)
for x := range assetTypes {
pairs, err := bi.FetchTradablePairs(ctx, assetTypes[x])
if err != nil {
Expand Down Expand Up @@ -2663,7 +2650,7 @@ func itemDecoder(s string) asset.Item {
switch s {
case "spot", "SPOT":
return asset.Spot
case "margin":
case "margin", "MARGIN":
return asset.Margin
case "futures", "USDT-FUTURES", "COIN-FUTURES", "USDC-FUTURES", "SUSD-FUTURES", "SCOIN-FUTURES", "SUSDC-FUTURES":
return asset.Futures
Expand Down Expand Up @@ -2859,3 +2846,27 @@ func (bi *Bitget) allFuturesOrderHelper(ctx context.Context, pairStr, productTyp
}
return resp, nil
}

// ItemEncoder encodes an asset.Item into a string
func itemEncoder(a asset.Item, pair currency.Pair) string {
switch a {
case asset.Spot:
return "SPOT"
case asset.Futures:
return getProductType(pair)
case asset.Margin, asset.CrossMargin:
return "MARGIN"
}
return ""
}

// PositionModeDecoder is a helper function that returns the appropriate position mode for a given string
func positionModeDecoder(s string) futures.PositionMode {
switch s {
case "one_way_mode":
return futures.OneWayMode
case "hedge_mode":
return futures.HedgeMode
}
return futures.UnknownMode
}
12 changes: 12 additions & 0 deletions exchanges/futures/futures.go
Original file line number Diff line number Diff line change
Expand Up @@ -1132,3 +1132,15 @@ func checkTrackerPrerequisitesLowerExchange(exch string, item asset.Item, cp cur
}
return exch, nil
}

// String implements the stringer interface
func (t PositionMode) String() string {
switch t {
case OneWayMode:
return "OneWay"
case HedgeMode:
return "Hedge"
default:
return ""
}
}
33 changes: 33 additions & 0 deletions exchanges/futures/futures_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,36 @@ type PositionSummary struct {
FrozenBalance decimal.Decimal
EquityOfCurrency decimal.Decimal
}

// PositionMode defines the different position modes supported by exchanges
type PositionMode uint8

// All supported position modes
const (
UnknownMode PositionMode = 0
OneWayMode PositionMode = 1 << iota
HedgeMode
)

// PositionHistory holds position history data
// Each exchange has their own requirements, so not all fields
// are required to be populated
type PositionHistory struct {
Exchange string
PositionID string
Pair currency.Pair
MarginCoin currency.Code
MarginType margin.Type
Side order.Side
PositionMode PositionMode
OpenAveragePrice float64
CloseAveragePrice float64
OpenSize float64
CloseSize float64
RealisedPnl float64
SettlementFee float64
OpenFee float64
CloseFee float64
StartDate time.Time
LastUpdated time.Time
}
2 changes: 1 addition & 1 deletion exchanges/stream/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func (w *Websocket) SetupNewConnection(c ConnectionSetup) error {
ExchangeName: w.exchangeName,
URL: connectionURL,
ProxyURL: w.GetProxyAddress(),
Verbose: true,
Verbose: w.verbose,
ResponseMaxLimit: c.ResponseMaxLimit,
Traffic: w.TrafficAlert,
readMessageErrors: w.ReadMessageErrors,
Expand Down

0 comments on commit 5583f09

Please sign in to comment.