mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
bbgo: fix account value calculation for mixed usd fiat
This commit is contained in:
parent
307c5f2a8d
commit
3b1725014b
|
@ -188,15 +188,24 @@ func (c *AccountValueCalculator) MarginLevel(ctx context.Context) (fixedpoint.Va
|
||||||
return marginLevel, nil
|
return marginLevel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func aggregateUsdValue(balances types.BalanceMap) fixedpoint.Value {
|
||||||
|
totalUsdValue := fixedpoint.Zero
|
||||||
|
// get all usd value if any
|
||||||
|
for currency, balance := range balances {
|
||||||
|
if types.IsUSDFiatCurrency(currency) {
|
||||||
|
totalUsdValue = totalUsdValue.Add(balance.Net())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalUsdValue
|
||||||
|
}
|
||||||
|
|
||||||
func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price, quantity, leverage fixedpoint.Value) (fixedpoint.Value, error) {
|
func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price, quantity, leverage fixedpoint.Value) (fixedpoint.Value, error) {
|
||||||
// default leverage guard
|
// default leverage guard
|
||||||
if leverage.IsZero() {
|
if leverage.IsZero() {
|
||||||
leverage = defaultLeverage
|
leverage = defaultLeverage
|
||||||
}
|
}
|
||||||
|
|
||||||
baseBalance, _ := session.Account.Balance(market.BaseCurrency)
|
|
||||||
quoteBalance, _ := session.Account.Balance(market.QuoteCurrency)
|
|
||||||
|
|
||||||
usingLeverage := session.Margin || session.IsolatedMargin || session.Futures || session.IsolatedFutures
|
usingLeverage := session.Margin || session.IsolatedMargin || session.Futures || session.IsolatedFutures
|
||||||
if !usingLeverage {
|
if !usingLeverage {
|
||||||
// For spot, we simply sell the base quoteCurrency
|
// For spot, we simply sell the base quoteCurrency
|
||||||
|
@ -215,6 +224,19 @@ func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price,
|
||||||
return quantity, fmt.Errorf("quantity is zero, can not submit sell order, please check your quantity settings")
|
return quantity, fmt.Errorf("quantity is zero, can not submit sell order, please check your quantity settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
baseBalance, _ := session.Account.Balance(market.BaseCurrency)
|
||||||
|
quoteBalance, _ := session.Account.Balance(market.QuoteCurrency)
|
||||||
|
balances := session.Account.Balances()
|
||||||
|
|
||||||
|
// for isolated margin we can calculate from these two pair
|
||||||
|
totalUsdValue := fixedpoint.Zero
|
||||||
|
if types.IsUSDFiatCurrency(market.QuoteCurrency) {
|
||||||
|
totalUsdValue = aggregateUsdValue(balances)
|
||||||
|
} else {
|
||||||
|
// TODO: translate quote currency like BTC of ETH/BTC to usd value
|
||||||
|
totalUsdValue = quoteBalance.Net()
|
||||||
|
}
|
||||||
|
|
||||||
if !quantity.IsZero() {
|
if !quantity.IsZero() {
|
||||||
return quantity, nil
|
return quantity, nil
|
||||||
}
|
}
|
||||||
|
@ -228,14 +250,13 @@ func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price,
|
||||||
|
|
||||||
// calculate the quantity automatically
|
// calculate the quantity automatically
|
||||||
if session.Margin || session.IsolatedMargin {
|
if session.Margin || session.IsolatedMargin {
|
||||||
|
|
||||||
baseBalanceValue := baseBalance.Net().Mul(price)
|
baseBalanceValue := baseBalance.Net().Mul(price)
|
||||||
accountValue := baseBalanceValue.Add(quoteBalance.Net())
|
accountUsdValue := baseBalanceValue.Add(totalUsdValue)
|
||||||
|
|
||||||
// avoid using all account value since there will be some trade loss for interests and the fee
|
// avoid using all account value since there will be some trade loss for interests and the fee
|
||||||
accountValue = accountValue.Mul(one.Sub(fixedpoint.NewFromFloat(0.01)))
|
accountUsdValue = accountUsdValue.Mul(one.Sub(fixedpoint.NewFromFloat(0.01)))
|
||||||
|
|
||||||
log.Infof("calculated account value %f %s", accountValue.Float64(), market.QuoteCurrency)
|
log.Infof("calculated account usd value %f %s", accountUsdValue.Float64(), market.QuoteCurrency)
|
||||||
|
|
||||||
originLeverage := leverage
|
originLeverage := leverage
|
||||||
if session.IsolatedMargin {
|
if session.IsolatedMargin {
|
||||||
|
@ -253,7 +274,7 @@ func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price,
|
||||||
}
|
}
|
||||||
|
|
||||||
// spot margin use the equity value, so we use the total quote balance here
|
// spot margin use the equity value, so we use the total quote balance here
|
||||||
maxPosition := risk.CalculateMaxPosition(price, accountValue, leverage)
|
maxPosition := risk.CalculateMaxPosition(price, accountUsdValue, leverage)
|
||||||
debt := baseBalance.Debt()
|
debt := baseBalance.Debt()
|
||||||
maxQuantity := maxPosition.Sub(debt)
|
maxQuantity := maxPosition.Sub(debt)
|
||||||
|
|
||||||
|
@ -262,7 +283,7 @@ func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price,
|
||||||
maxPosition.Float64(),
|
maxPosition.Float64(),
|
||||||
debt.Float64(),
|
debt.Float64(),
|
||||||
price.Float64(),
|
price.Float64(),
|
||||||
accountValue.Float64(),
|
accountUsdValue.Float64(),
|
||||||
market.QuoteCurrency,
|
market.QuoteCurrency,
|
||||||
leverage.Float64())
|
leverage.Float64())
|
||||||
|
|
||||||
|
@ -271,10 +292,10 @@ func CalculateBaseQuantity(session *ExchangeSession, market types.Market, price,
|
||||||
|
|
||||||
if session.Futures || session.IsolatedFutures {
|
if session.Futures || session.IsolatedFutures {
|
||||||
// TODO: get mark price here
|
// TODO: get mark price here
|
||||||
maxPositionQuantity := risk.CalculateMaxPosition(price, quoteBalance.Available, leverage)
|
maxPositionQuantity := risk.CalculateMaxPosition(price, totalUsdValue, leverage)
|
||||||
requiredPositionCost := risk.CalculatePositionCost(price, price, maxPositionQuantity, leverage, types.SideTypeSell)
|
requiredPositionCost := risk.CalculatePositionCost(price, price, maxPositionQuantity, leverage, types.SideTypeSell)
|
||||||
if quoteBalance.Available.Compare(requiredPositionCost) < 0 {
|
if quoteBalance.Available.Compare(requiredPositionCost) < 0 {
|
||||||
return maxPositionQuantity, fmt.Errorf("available margin %f %s is not enough, can not submit order", quoteBalance.Available.Float64(), market.QuoteCurrency)
|
return maxPositionQuantity, fmt.Errorf("margin total usd value %f is not enough, can not submit order", totalUsdValue.Float64())
|
||||||
}
|
}
|
||||||
|
|
||||||
return maxPositionQuantity, nil
|
return maxPositionQuantity, nil
|
||||||
|
@ -290,7 +311,6 @@ func CalculateQuoteQuantity(ctx context.Context, session *ExchangeSession, quote
|
||||||
}
|
}
|
||||||
|
|
||||||
quoteBalance, _ := session.Account.Balance(quoteCurrency)
|
quoteBalance, _ := session.Account.Balance(quoteCurrency)
|
||||||
accountValue := NewAccountValueCalculator(session, quoteCurrency)
|
|
||||||
|
|
||||||
usingLeverage := session.Margin || session.IsolatedMargin || session.Futures || session.IsolatedFutures
|
usingLeverage := session.Margin || session.IsolatedMargin || session.Futures || session.IsolatedFutures
|
||||||
if !usingLeverage {
|
if !usingLeverage {
|
||||||
|
@ -298,7 +318,23 @@ func CalculateQuoteQuantity(ctx context.Context, session *ExchangeSession, quote
|
||||||
return quoteBalance.Available.Mul(fixedpoint.Min(leverage, fixedpoint.One)), nil
|
return quoteBalance.Available.Mul(fixedpoint.Min(leverage, fixedpoint.One)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
originLeverage := leverage
|
||||||
|
if session.IsolatedMargin {
|
||||||
|
leverage = fixedpoint.Min(leverage, maxIsolatedMarginLeverage)
|
||||||
|
log.Infof("using isolated margin, maxLeverage=%f originalLeverage=%f currentLeverage=%f",
|
||||||
|
maxIsolatedMarginLeverage.Float64(),
|
||||||
|
originLeverage.Float64(),
|
||||||
|
leverage.Float64())
|
||||||
|
} else {
|
||||||
|
leverage = fixedpoint.Min(leverage, maxCrossMarginLeverage)
|
||||||
|
log.Infof("using cross margin, maxLeverage=%f originalLeverage=%f currentLeverage=%f",
|
||||||
|
maxCrossMarginLeverage.Float64(),
|
||||||
|
originLeverage.Float64(),
|
||||||
|
leverage.Float64())
|
||||||
|
}
|
||||||
|
|
||||||
// using leverage -- starts from here
|
// using leverage -- starts from here
|
||||||
|
accountValue := NewAccountValueCalculator(session, quoteCurrency)
|
||||||
availableQuote, err := accountValue.AvailableQuote(ctx)
|
availableQuote, err := accountValue.AvailableQuote(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Errorf("can not update available quote")
|
log.WithError(err).Errorf("can not update available quote")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user