mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-25 16:25:16 +00:00
bbgo: add test case for calculateNetValueInQuote
This commit is contained in:
parent
7617679651
commit
809294b054
|
@ -115,32 +115,37 @@ func (c *AccountValueCalculator) MarketValue(ctx context.Context) (fixedpoint.Va
|
|||
}
|
||||
|
||||
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
|
||||
return fixedpoint.Zero, err
|
||||
}
|
||||
}
|
||||
|
||||
balances := c.session.Account.Balances()
|
||||
accountValue := calculateNetValueInQuote(balances, c.prices, c.quoteCurrency)
|
||||
return accountValue, nil
|
||||
}
|
||||
|
||||
func calculateNetValueInQuote(balances types.BalanceMap, prices map[string]fixedpoint.Value, quoteCurrency string) (accountValue fixedpoint.Value) {
|
||||
accountValue = fixedpoint.Zero
|
||||
|
||||
for _, b := range balances {
|
||||
if b.Currency == c.quoteCurrency {
|
||||
if b.Currency == quoteCurrency {
|
||||
accountValue = accountValue.Add(b.Net())
|
||||
continue
|
||||
}
|
||||
|
||||
symbol := b.Currency + c.quoteCurrency // for BTC/USDT, ETH/USDT pairs
|
||||
symbolReverse := c.quoteCurrency + b.Currency // for USDT/USDC or USDT/TWD pairs
|
||||
if price, ok := c.prices[symbol]; ok {
|
||||
symbol := b.Currency + quoteCurrency // for BTC/USDT, ETH/USDT pairs
|
||||
symbolReverse := quoteCurrency + b.Currency // for USDT/USDC or USDT/TWD pairs
|
||||
if price, ok := prices[symbol]; ok {
|
||||
accountValue = accountValue.Add(b.Net().Mul(price))
|
||||
} else if priceReverse, ok2 := c.prices[symbolReverse]; ok2 {
|
||||
} else if priceReverse, ok2 := prices[symbolReverse]; ok2 {
|
||||
price2 := one.Div(priceReverse)
|
||||
accountValue = accountValue.Add(b.Net().Mul(price2))
|
||||
}
|
||||
}
|
||||
|
||||
return accountValue, nil
|
||||
return accountValue
|
||||
}
|
||||
|
||||
func (c *AccountValueCalculator) AvailableQuote(ctx context.Context) (fixedpoint.Value, error) {
|
||||
|
@ -189,7 +194,7 @@ func (c *AccountValueCalculator) MarginLevel(ctx context.Context) (fixedpoint.Va
|
|||
return marginLevel, nil
|
||||
}
|
||||
|
||||
func aggregateUsdValue(balances types.BalanceMap) fixedpoint.Value {
|
||||
func aggregateUsdNetValue(balances types.BalanceMap) fixedpoint.Value {
|
||||
totalUsdValue := fixedpoint.Zero
|
||||
// get all usd value if any
|
||||
for currency, balance := range balances {
|
||||
|
@ -247,7 +252,7 @@ func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price,
|
|||
// for isolated margin we can calculate from these two pair
|
||||
totalUsdValue := fixedpoint.Zero
|
||||
if len(restBalances) == 1 && types.IsUSDFiatCurrency(market.QuoteCurrency) {
|
||||
totalUsdValue = aggregateUsdValue(balances)
|
||||
totalUsdValue = aggregateUsdNetValue(balances)
|
||||
} else if len(restBalances) > 1 {
|
||||
accountValue := NewAccountValueCalculator(session, "USDT")
|
||||
netValue, err := accountValue.NetValue(context.Background())
|
||||
|
@ -258,7 +263,7 @@ func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price,
|
|||
totalUsdValue = netValue
|
||||
} else {
|
||||
// TODO: translate quote currency like BTC of ETH/BTC to usd value
|
||||
totalUsdValue = aggregateUsdValue(usdBalances)
|
||||
totalUsdValue = aggregateUsdNetValue(usdBalances)
|
||||
}
|
||||
|
||||
if !quantity.IsZero() {
|
||||
|
@ -270,7 +275,7 @@ func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price,
|
|||
}
|
||||
|
||||
// using leverage -- starts from here
|
||||
log.Infof("calculating available leveraged base quantity: base balance = %+v, quote balance = %+v", baseBalance, quoteBalance)
|
||||
log.Infof("calculating available leveraged base quantity: base balance = %+v, total usd value %f", baseBalance, totalUsdValue.Float64())
|
||||
|
||||
// calculate the quantity automatically
|
||||
if session.Margin || session.IsolatedMargin {
|
||||
|
|
|
@ -184,7 +184,7 @@ func Test_aggregateUsdValue(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, aggregateUsdValue(tt.args.balances), "aggregateUsdValue(%v)", tt.args.balances)
|
||||
assert.Equalf(t, tt.want, aggregateUsdNetValue(tt.args.balances), "aggregateUsdNetValue(%v)", tt.args.balances)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -226,3 +226,78 @@ func Test_usdFiatBalances(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_calculateNetValueInQuote(t *testing.T) {
|
||||
type args struct {
|
||||
balances types.BalanceMap
|
||||
prices map[string]fixedpoint.Value
|
||||
quoteCurrency string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantAccountValue fixedpoint.Value
|
||||
}{
|
||||
{
|
||||
name: "positive asset",
|
||||
args: args{
|
||||
balances: types.BalanceMap{
|
||||
"USDC": types.Balance{Currency: "USDC", Available: number(70.0)},
|
||||
"USDT": types.Balance{Currency: "USDT", Available: number(100.0)},
|
||||
"BUSD": types.Balance{Currency: "BUSD", Available: number(80.0)},
|
||||
"BTC": types.Balance{Currency: "BTC", Available: number(0.01)},
|
||||
},
|
||||
prices: map[string]fixedpoint.Value{
|
||||
"USDCUSDT": number(1.0),
|
||||
"BUSDUSDT": number(1.0),
|
||||
"BTCUSDT": number(19000.0),
|
||||
},
|
||||
quoteCurrency: "USDT",
|
||||
},
|
||||
wantAccountValue: number(19000.0*0.01 + 100.0 + 80.0 + 70.0),
|
||||
},
|
||||
{
|
||||
name: "borrow base asset",
|
||||
args: args{
|
||||
balances: types.BalanceMap{
|
||||
"USDT": types.Balance{Currency: "USDT", Available: number(20000.0 * 2)},
|
||||
"USDC": types.Balance{Currency: "USDC", Available: number(70.0)},
|
||||
"BUSD": types.Balance{Currency: "BUSD", Available: number(80.0)},
|
||||
"BTC": types.Balance{Currency: "BTC", Available: number(0), Borrowed: number(2.0)},
|
||||
},
|
||||
prices: map[string]fixedpoint.Value{
|
||||
"USDCUSDT": number(1.0),
|
||||
"BUSDUSDT": number(1.0),
|
||||
"BTCUSDT": number(19000.0),
|
||||
},
|
||||
quoteCurrency: "USDT",
|
||||
},
|
||||
wantAccountValue: number(19000.0*-2.0 + 20000.0*2 + 80.0 + 70.0),
|
||||
},
|
||||
{
|
||||
name: "multi base asset",
|
||||
args: args{
|
||||
balances: types.BalanceMap{
|
||||
"USDT": types.Balance{Currency: "USDT", Available: number(20000.0 * 2)},
|
||||
"USDC": types.Balance{Currency: "USDC", Available: number(70.0)},
|
||||
"BUSD": types.Balance{Currency: "BUSD", Available: number(80.0)},
|
||||
"ETH": types.Balance{Currency: "ETH", Available: number(10.0)},
|
||||
"BTC": types.Balance{Currency: "BTC", Available: number(0), Borrowed: number(2.0)},
|
||||
},
|
||||
prices: map[string]fixedpoint.Value{
|
||||
"USDCUSDT": number(1.0),
|
||||
"BUSDUSDT": number(1.0),
|
||||
"ETHUSDT": number(1700.0),
|
||||
"BTCUSDT": number(19000.0),
|
||||
},
|
||||
quoteCurrency: "USDT",
|
||||
},
|
||||
wantAccountValue: number(19000.0*-2.0 + 1700.0*10.0 + 20000.0*2 + 80.0 + 70.0),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equalf(t, tt.wantAccountValue, calculateNetValueInQuote(tt.args.balances, tt.args.prices, tt.args.quoteCurrency), "calculateNetValueInQuote(%v, %v, %v)", tt.args.balances, tt.args.prices, tt.args.quoteCurrency)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ func (b Balance) Debt() fixedpoint.Value {
|
|||
}
|
||||
|
||||
func (b Balance) ValueString() (o string) {
|
||||
o = b.Available.String()
|
||||
o = b.Net().String()
|
||||
|
||||
if b.Locked.Sign() > 0 {
|
||||
o += fmt.Sprintf(" (locked %v)", b.Locked)
|
||||
|
@ -64,7 +64,7 @@ func (b Balance) ValueString() (o string) {
|
|||
}
|
||||
|
||||
func (b Balance) String() (o string) {
|
||||
o = fmt.Sprintf("%s: %s", b.Currency, b.Available.String())
|
||||
o = fmt.Sprintf("%s: %s", b.Currency, b.Net().String())
|
||||
|
||||
if b.Locked.Sign() > 0 {
|
||||
o += fmt.Sprintf(" (locked %v)", b.Locked)
|
||||
|
@ -74,6 +74,10 @@ func (b Balance) String() (o string) {
|
|||
o += fmt.Sprintf(" (borrowed: %v)", b.Borrowed)
|
||||
}
|
||||
|
||||
if b.Interest.Sign() > 0 {
|
||||
o += fmt.Sprintf(" (interest: %v)", b.Interest)
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user