pull out AccountValueCalculator

This commit is contained in:
c9s 2022-07-21 19:46:58 +08:00
parent 15879adf3b
commit 76def2fe9d
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
3 changed files with 109 additions and 6 deletions

View File

@ -74,7 +74,7 @@ func (reporter *AverageCostPnLReporter) Run() {
} }
for _, symbol := range reporter.Symbols { for _, symbol := range reporter.Symbols {
report := calculator.Calculate(symbol, session.Trades[symbol].Copy(), session.lastPrices[symbol]) report := calculator.NetValue(symbol, session.Trades[symbol].Copy(), session.lastPrices[symbol])
report.Print() report.Print()
} }
} }

View File

@ -3,6 +3,7 @@ package pivotshort
import ( import (
"context" "context"
"fmt" "fmt"
"time"
"github.com/c9s/bbgo/pkg/bbgo" "github.com/c9s/bbgo/pkg/bbgo"
"github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/fixedpoint"
@ -239,17 +240,115 @@ func (s *BreakLow) Bind(session *bbgo.ExchangeSession, orderExecutor *bbgo.Gener
})) }))
} }
type AccountValueCalculator struct {
session *bbgo.ExchangeSession
quoteCurrency string
prices map[string]fixedpoint.Value
tickers map[string]types.Ticker
updateTime time.Time
}
func NewAccountValueCalculator(session *bbgo.ExchangeSession, quoteCurrency string) *AccountValueCalculator {
return &AccountValueCalculator{
session: session,
quoteCurrency: quoteCurrency,
prices: make(map[string]fixedpoint.Value),
tickers: make(map[string]types.Ticker),
}
}
func (c *AccountValueCalculator) UpdatePrices(ctx context.Context) error {
balances := c.session.Account.Balances()
currencies := balances.Currencies()
var symbols []string
for _, currency := range currencies {
symbol := currency + c.quoteCurrency
symbols = append(symbols, symbol)
}
tickers, err := c.session.Exchange.QueryTickers(ctx, symbols...)
if err != nil {
return err
}
c.tickers = tickers
for symbol, ticker := range tickers {
c.prices[symbol] = ticker.Last
if ticker.Time.After(c.updateTime) {
c.updateTime = ticker.Time
}
}
return nil
}
func (c *AccountValueCalculator) DebtValue(ctx context.Context) (fixedpoint.Value, error) {
debtValue := fixedpoint.Zero
if len(c.prices) == 0 {
if err := c.UpdatePrices(ctx); err != nil {
return debtValue, err
}
}
balances := c.session.Account.Balances()
for _, b := range balances {
symbol := b.Currency + c.quoteCurrency
price, ok := c.prices[symbol]
if !ok {
continue
}
debtValue = debtValue.Add(b.Debt().Mul(price))
}
return debtValue, nil
}
func (c *AccountValueCalculator) NetValue(ctx context.Context) (fixedpoint.Value, error) {
accountValue := fixedpoint.Zero
if len(c.prices) == 0 {
if err := c.UpdatePrices(ctx); err != nil {
return accountValue, err
}
}
balances := c.session.Account.Balances()
for _, b := range balances {
symbol := b.Currency + c.quoteCurrency
price, ok := c.prices[symbol]
if !ok {
continue
}
accountValue = accountValue.Add(b.Net().Mul(price))
}
return accountValue, nil
}
func calculateAccountNetValue(session *bbgo.ExchangeSession) (fixedpoint.Value, error) {
accountValue := fixedpoint.Zero
ctx := context.Background()
c := NewAccountValueCalculator(session, "USDT")
if err := c.UpdatePrices(ctx); err != nil {
return accountValue, err
}
return c.NetValue(ctx)
}
func useQuantityOrBaseBalance(session *bbgo.ExchangeSession, market types.Market, price, quantity, leverage fixedpoint.Value) (fixedpoint.Value, error) { func useQuantityOrBaseBalance(session *bbgo.ExchangeSession, market types.Market, price, quantity, leverage fixedpoint.Value) (fixedpoint.Value, error) {
if leverage.IsZero() {
leverage = fixedpoint.NewFromInt(3)
}
usingLeverage := session.Margin || session.IsolatedMargin || session.Futures || session.IsolatedFutures usingLeverage := session.Margin || session.IsolatedMargin || session.Futures || session.IsolatedFutures
if usingLeverage { if usingLeverage {
if !quantity.IsZero() { if !quantity.IsZero() {
return quantity, nil return quantity, nil
} }
if leverage.IsZero() {
leverage = fixedpoint.NewFromInt(3)
}
// quantity is zero, we need to calculate the quantity // quantity is zero, we need to calculate the quantity
baseBalance, _ := session.Account.Balance(market.BaseCurrency) baseBalance, _ := session.Account.Balance(market.BaseCurrency)
quoteBalance, _ := session.Account.Balance(market.QuoteCurrency) quoteBalance, _ := session.Account.Balance(market.QuoteCurrency)
@ -300,7 +399,7 @@ func useQuantityOrBaseBalance(session *bbgo.ExchangeSession, market types.Market
} }
// For spot, we simply sell the base currency // For spot, we simply sell the base quoteCurrency
balance, hasBalance := session.Account.Balance(market.BaseCurrency) balance, hasBalance := session.Account.Balance(market.BaseCurrency)
if hasBalance { if hasBalance {
if quantity.IsZero() { if quantity.IsZero() {

View File

@ -49,6 +49,10 @@ func (b Balance) Net() fixedpoint.Value {
return netAsset return netAsset
} }
func (b Balance) Debt() fixedpoint.Value {
return b.Borrowed.Add(b.Interest)
}
func (b Balance) ValueString() (o string) { func (b Balance) ValueString() (o string) {
o = b.Available.String() o = b.Available.String()