Merge pull request #1702 from c9s/c9s/core/improve-metrics

IMPROVE: improve balance related metrics
This commit is contained in:
c9s 2024-08-22 10:02:51 +08:00 committed by GitHub
commit 6718087cb1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 228 additions and 133 deletions

View File

@ -9,35 +9,94 @@ var (
Help: "bbgo exchange session connection status",
},
[]string{
"exchange", // exchange name
"channel", // channel: user or market
"margin", // margin type: none, margin or isolated
"symbol", // margin symbol of the connection.
"session",
"exchange", // exchange name
"channel", // channel: user or market
"margin_type", // margin type: none, margin or isolated
"symbol", // margin symbol of the connection.
},
)
metricsLockedBalances = prometheus.NewGaugeVec(
metricsBalanceLockedMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "bbgo_balances_locked",
Help: "bbgo exchange locked balances",
},
[]string{
"exchange", // exchange name
"margin", // margin of connection. 1 or 0
"symbol", // margin symbol of the connection.
"session",
"exchange", // exchange name
"margin_type", // margin of connection. 1 or 0
"symbol", // margin symbol of the connection.
"currency",
},
)
metricsAvailableBalances = prometheus.NewGaugeVec(
metricsBalanceAvailableMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "bbgo_balances_available",
Help: "bbgo exchange available balances",
},
[]string{
"exchange", // exchange name
"margin", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"session",
"exchange", // exchange name
"margin_type", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"currency",
},
)
metricsBalanceDebtMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "bbgo_balances_debt",
Help: "bbgo exchange balance debt",
},
[]string{
"session",
"exchange", // exchange name
"margin_type", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"currency",
},
)
metricsBalanceBorrowedMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "bbgo_balances_borrowed",
Help: "bbgo exchange balance borrowed",
},
[]string{
"session",
"exchange", // exchange name
"margin_type", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"currency",
},
)
metricsBalanceInterestMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "bbgo_balances_interest",
Help: "bbgo exchange balance interest",
},
[]string{
"session",
"exchange", // exchange name
"margin_type", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"currency",
},
)
metricsBalanceNetMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "bbgo_balances_net",
Help: "bbgo exchange session total net balances",
},
[]string{
"session",
"exchange", // exchange name
"margin_type", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"currency",
},
)
@ -48,9 +107,10 @@ var (
Help: "bbgo exchange session total balances",
},
[]string{
"exchange", // exchange name
"margin", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"session",
"exchange", // exchange name
"margin_type", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"currency",
},
)
@ -61,11 +121,12 @@ var (
Help: "bbgo exchange session trades",
},
[]string{
"exchange", // exchange name
"margin", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"side", // side: buy or sell
"liquidity", // maker or taker
"session",
"exchange", // exchange name
"margin_type", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"side", // side: buy or sell
"liquidity", // maker or taker
},
)
@ -75,26 +136,28 @@ var (
Help: "bbgo trading volume",
},
[]string{
"exchange", // exchange name
"margin", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"side", // side: buy or sell
"liquidity", // maker or taker
"session",
"exchange", // exchange name
"margin_type", // margin of connection. none, margin or isolated
"symbol", // margin symbol of the connection.
"side", // side: buy or sell
"liquidity", // maker or taker
},
)
metricsLastUpdateTimeBalance = prometheus.NewGaugeVec(
metricsLastUpdateTimeMetrics = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "bbgo_last_update_time",
Help: "bbgo last update time of different channel",
},
[]string{
"exchange", // exchange name
"margin", // margin of connection. none, margin or isolated
"channel", // channel: user, market
"data_type", // type: balance, ticker, kline, orderbook, trade, order
"symbol", // for market data, trade and order
"currency", // for balance
"session",
"exchange", // exchange name
"margin_type", // margin of connection. none, margin or isolated
"channel", // channel: user, market
"data_type", // type: balance, ticker, kline, orderbook, trade, order
"symbol", // for market data, trade and order
"currency", // for balance
},
)
)
@ -103,10 +166,14 @@ func init() {
prometheus.MustRegister(
metricsConnectionStatus,
metricsTotalBalances,
metricsLockedBalances,
metricsAvailableBalances,
metricsBalanceNetMetrics,
metricsBalanceLockedMetrics,
metricsBalanceAvailableMetrics,
metricsBalanceDebtMetrics,
metricsBalanceBorrowedMetrics,
metricsBalanceInterestMetrics,
metricsTradesTotal,
metricsTradingVolume,
metricsLastUpdateTimeBalance,
metricsLastUpdateTimeMetrics,
)
}

View File

@ -54,11 +54,11 @@ type ExchangeSession struct {
PublicOnly bool `json:"publicOnly,omitempty" yaml:"publicOnly"`
// PrivateChannels is used for filtering the private user data channel, .e.g, orders, trades, balances.. etc
// This option is exchange specific
// This option is exchange-specific, currently only MAX exchange reads this option
PrivateChannels []string `json:"privateChannels,omitempty" yaml:"privateChannels,omitempty"`
// PrivateChannelSymbols is used for filtering the private user data channel, .e.g, order symbol subscription.
// This option is exchange specific
// This option is exchange-specific, currently only Bitget exchange reads this option
PrivateChannelSymbols []string `json:"privateChannelSymbols,omitempty" yaml:"privateChannelSymbols,omitempty"`
Margin bool `json:"margin,omitempty" yaml:"margin"`
@ -886,91 +886,106 @@ func (session *ExchangeSession) InitExchange(name string, ex types.Exchange) err
return nil
}
func (session *ExchangeSession) MarginType() string {
margin := "none"
func (session *ExchangeSession) MarginType() types.MarginType {
if session.Margin {
margin = "margin"
if session.IsolatedMargin {
margin = "isolated"
return types.MarginTypeIsolatedMargin
} else {
return types.MarginTypeCrossMargin
}
}
return margin
return types.MarginTypeSpot
}
func (session *ExchangeSession) metricsBalancesUpdater(balances types.BalanceMap) {
for currency, balance := range balances {
labels := prometheus.Labels{
"exchange": session.ExchangeName.String(),
"margin": session.MarginType(),
"symbol": session.IsolatedMarginSymbol,
"currency": currency,
"session": session.Name,
"exchange": session.ExchangeName.String(),
"margin_type": string(session.MarginType()),
"symbol": session.IsolatedMarginSymbol,
"currency": currency,
}
metricsTotalBalances.With(labels).Set(balance.Total().Float64())
metricsLockedBalances.With(labels).Set(balance.Locked.Float64())
metricsAvailableBalances.With(labels).Set(balance.Available.Float64())
metricsLastUpdateTimeBalance.With(prometheus.Labels{
"exchange": session.ExchangeName.String(),
"margin": session.MarginType(),
"channel": "user",
"data_type": "balance",
"symbol": "",
"currency": currency,
metricsBalanceNetMetrics.With(labels).Set(balance.Net().Float64())
metricsBalanceAvailableMetrics.With(labels).Set(balance.Available.Float64())
metricsBalanceLockedMetrics.With(labels).Set(balance.Locked.Float64())
// margin metrics
metricsBalanceDebtMetrics.With(labels).Set(balance.Debt().Float64())
metricsBalanceBorrowedMetrics.With(labels).Set(balance.Borrowed.Float64())
metricsBalanceInterestMetrics.With(labels).Set(balance.Interest.Float64())
metricsLastUpdateTimeMetrics.With(prometheus.Labels{
"session": session.Name,
"exchange": session.ExchangeName.String(),
"margin_type": string(session.MarginType()),
"channel": "user",
"data_type": "balance",
"symbol": "",
"currency": currency,
}).SetToCurrentTime()
}
}
func (session *ExchangeSession) metricsOrderUpdater(order types.Order) {
metricsLastUpdateTimeBalance.With(prometheus.Labels{
"exchange": session.ExchangeName.String(),
"margin": session.MarginType(),
"channel": "user",
"data_type": "order",
"symbol": order.Symbol,
"currency": "",
metricsLastUpdateTimeMetrics.With(prometheus.Labels{
"session": session.Name,
"exchange": session.ExchangeName.String(),
"margin_type": string(session.MarginType()),
"channel": "user",
"data_type": "order",
"symbol": order.Symbol,
"currency": "",
}).SetToCurrentTime()
}
func (session *ExchangeSession) metricsTradeUpdater(trade types.Trade) {
labels := prometheus.Labels{
"exchange": session.ExchangeName.String(),
"margin": session.MarginType(),
"side": trade.Side.String(),
"symbol": trade.Symbol,
"liquidity": trade.Liquidity(),
"session": session.Name,
"exchange": session.ExchangeName.String(),
"margin_type": string(session.MarginType()),
"side": trade.Side.String(),
"symbol": trade.Symbol,
"liquidity": trade.Liquidity(),
}
metricsTradingVolume.With(labels).Add(trade.Quantity.Mul(trade.Price).Float64())
metricsTradesTotal.With(labels).Inc()
metricsLastUpdateTimeBalance.With(prometheus.Labels{
"exchange": session.ExchangeName.String(),
"margin": session.MarginType(),
"channel": "user",
"data_type": "trade",
"symbol": trade.Symbol,
"currency": "",
metricsLastUpdateTimeMetrics.With(prometheus.Labels{
"session": session.Name,
"exchange": session.ExchangeName.String(),
"margin_type": string(session.MarginType()),
"channel": "user",
"data_type": "trade",
"symbol": trade.Symbol,
"currency": "",
}).SetToCurrentTime()
}
func (session *ExchangeSession) bindMarketDataStreamMetrics(stream types.Stream) {
stream.OnBookUpdate(func(book types.SliceOrderBook) {
metricsLastUpdateTimeBalance.With(prometheus.Labels{
"exchange": session.ExchangeName.String(),
"margin": session.MarginType(),
"channel": "market",
"data_type": "book",
"symbol": book.Symbol,
"currency": "",
metricsLastUpdateTimeMetrics.With(prometheus.Labels{
"session": session.Name,
"exchange": session.ExchangeName.String(),
"margin_type": string(session.MarginType()),
"channel": "market",
"data_type": "book",
"symbol": book.Symbol,
"currency": "",
}).SetToCurrentTime()
})
stream.OnKLineClosed(func(kline types.KLine) {
metricsLastUpdateTimeBalance.With(prometheus.Labels{
"exchange": session.ExchangeName.String(),
"margin": session.MarginType(),
"channel": "market",
"data_type": "kline",
"symbol": kline.Symbol,
"currency": "",
metricsLastUpdateTimeMetrics.With(prometheus.Labels{
"session": session.Name,
"exchange": session.ExchangeName.String(),
"margin_type": string(session.MarginType()),
"channel": "market",
"data_type": "kline",
"symbol": kline.Symbol,
"currency": "",
}).SetToCurrentTime()
})
}
@ -982,18 +997,20 @@ func (session *ExchangeSession) bindUserDataStreamMetrics(stream types.Stream) {
stream.OnOrderUpdate(session.metricsOrderUpdater)
stream.OnDisconnect(func() {
metricsConnectionStatus.With(prometheus.Labels{
"channel": "user",
"exchange": session.ExchangeName.String(),
"margin": session.MarginType(),
"symbol": session.IsolatedMarginSymbol,
"channel": "user",
"session": session.Name,
"exchange": session.ExchangeName.String(),
"margin_type": string(session.MarginType()),
"symbol": session.IsolatedMarginSymbol,
}).Set(0.0)
})
stream.OnConnect(func() {
metricsConnectionStatus.With(prometheus.Labels{
"channel": "user",
"exchange": session.ExchangeName.String(),
"margin": session.MarginType(),
"symbol": session.IsolatedMarginSymbol,
"channel": "user",
"session": session.Name,
"exchange": session.ExchangeName.String(),
"margin_type": string(session.MarginType()),
"symbol": session.IsolatedMarginSymbol,
}).Set(1.0)
})
}

42
pkg/types/futures.go Normal file
View File

@ -0,0 +1,42 @@
package types
import "github.com/c9s/bbgo/pkg/fixedpoint"
type FuturesExchange interface {
UseFutures()
UseIsolatedFutures(symbol string)
GetFuturesSettings() FuturesSettings
}
type FuturesSettings struct {
IsFutures bool
IsIsolatedFutures bool
IsolatedFuturesSymbol string
}
func (s FuturesSettings) GetFuturesSettings() FuturesSettings {
return s
}
func (s *FuturesSettings) UseFutures() {
s.IsFutures = true
}
func (s *FuturesSettings) UseIsolatedFutures(symbol string) {
s.IsFutures = true
s.IsIsolatedFutures = true
s.IsolatedFuturesSymbol = symbol
}
// FuturesUserAsset define cross/isolated futures account asset
type FuturesUserAsset struct {
Asset string `json:"asset"`
InitialMargin fixedpoint.Value `json:"initialMargin"`
MaintMargin fixedpoint.Value `json:"maintMargin"`
MarginBalance fixedpoint.Value `json:"marginBalance"`
MaxWithdrawAmount fixedpoint.Value `json:"maxWithdrawAmount"`
OpenOrderInitialMargin fixedpoint.Value `json:"openOrderInitialMargin"`
PositionInitialMargin fixedpoint.Value `json:"positionInitialMargin"`
UnrealizedProfit fixedpoint.Value `json:"unrealizedProfit"`
WalletBalance fixedpoint.Value `json:"walletBalance"`
}

View File

@ -7,44 +7,13 @@ import (
"github.com/c9s/bbgo/pkg/fixedpoint"
)
type FuturesExchange interface {
UseFutures()
UseIsolatedFutures(symbol string)
GetFuturesSettings() FuturesSettings
}
type MarginType string
type FuturesSettings struct {
IsFutures bool
IsIsolatedFutures bool
IsolatedFuturesSymbol string
}
func (s FuturesSettings) GetFuturesSettings() FuturesSettings {
return s
}
func (s *FuturesSettings) UseFutures() {
s.IsFutures = true
}
func (s *FuturesSettings) UseIsolatedFutures(symbol string) {
s.IsFutures = true
s.IsIsolatedFutures = true
s.IsolatedFuturesSymbol = symbol
}
// FuturesUserAsset define cross/isolated futures account asset
type FuturesUserAsset struct {
Asset string `json:"asset"`
InitialMargin fixedpoint.Value `json:"initialMargin"`
MaintMargin fixedpoint.Value `json:"maintMargin"`
MarginBalance fixedpoint.Value `json:"marginBalance"`
MaxWithdrawAmount fixedpoint.Value `json:"maxWithdrawAmount"`
OpenOrderInitialMargin fixedpoint.Value `json:"openOrderInitialMargin"`
PositionInitialMargin fixedpoint.Value `json:"positionInitialMargin"`
UnrealizedProfit fixedpoint.Value `json:"unrealizedProfit"`
WalletBalance fixedpoint.Value `json:"walletBalance"`
}
const (
MarginTypeSpot MarginType = "spot"
MarginTypeCrossMargin MarginType = "cross_margin"
MarginTypeIsolatedMargin MarginType = "isolated_margin"
)
type MarginExchange interface {
UseMargin()