Merge pull request #138 from c9s/feature/global-margin-structure

feature: convert and parse binance margin structure into global types
This commit is contained in:
Yo-An Lin 2021-02-28 16:13:48 +08:00 committed by GitHub
commit a52f487d4e
4 changed files with 164 additions and 4 deletions

View File

@ -9,10 +9,87 @@ import (
"github.com/pkg/errors"
"github.com/c9s/bbgo/pkg/datatype"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
"github.com/c9s/bbgo/pkg/util"
)
func toGlobalIsolatedUserAsset(userAsset binance.IsolatedUserAsset) types.IsolatedUserAsset {
return types.IsolatedUserAsset{
Asset: userAsset.Asset,
Borrowed: fixedpoint.MustNewFromString(userAsset.Borrowed),
Free: fixedpoint.MustNewFromString(userAsset.Free),
Interest: fixedpoint.MustNewFromString(userAsset.Interest),
Locked: fixedpoint.MustNewFromString(userAsset.Locked),
NetAsset: fixedpoint.MustNewFromString(userAsset.NetAsset),
NetAssetOfBtc: fixedpoint.MustNewFromString(userAsset.NetAssetOfBtc),
BorrowEnabled: userAsset.BorrowEnabled,
RepayEnabled: userAsset.RepayEnabled,
TotalAsset: fixedpoint.MustNewFromString(userAsset.TotalAsset),
}
}
func toGlobalIsolatedMarginAsset(asset binance.IsolatedMarginAsset) types.IsolatedMarginAsset {
return types.IsolatedMarginAsset{
Symbol: asset.Symbol,
QuoteAsset: toGlobalIsolatedUserAsset(asset.QuoteAsset),
BaseAsset: toGlobalIsolatedUserAsset(asset.BaseAsset),
IsolatedCreated: asset.IsolatedCreated,
MarginLevel: fixedpoint.MustNewFromString(asset.MarginLevel),
MarginLevelStatus: asset.MarginLevelStatus,
MarginRatio: fixedpoint.MustNewFromString(asset.MarginRatio),
IndexPrice: fixedpoint.MustNewFromString(asset.IndexPrice),
LiquidatePrice: fixedpoint.MustNewFromString(asset.LiquidatePrice),
LiquidateRate: fixedpoint.MustNewFromString(asset.LiquidateRate),
TradeEnabled: false,
}
}
func toGlobalIsolatedMarginAssets(assets []binance.IsolatedMarginAsset) (retAssets []types.IsolatedMarginAsset) {
for _, asset := range assets {
retAssets = append(retAssets, toGlobalIsolatedMarginAsset(asset))
}
return retAssets
}
func toGlobalIsolatedMarginAccount(account *binance.IsolatedMarginAccount) *types.IsolatedMarginAccount {
return &types.IsolatedMarginAccount{
TotalAssetOfBTC: fixedpoint.MustNewFromString(account.TotalNetAssetOfBTC),
TotalLiabilityOfBTC: fixedpoint.MustNewFromString(account.TotalLiabilityOfBTC),
TotalNetAssetOfBTC: fixedpoint.MustNewFromString(account.TotalNetAssetOfBTC),
Assets: toGlobalIsolatedMarginAssets(account.Assets),
}
}
func toGlobalMarginUserAssets(userAssets []binance.UserAsset) (retAssets []types.MarginUserAsset) {
for _, asset := range userAssets {
retAssets = append(retAssets, types.MarginUserAsset{
Asset: asset.Asset,
Borrowed: fixedpoint.MustNewFromString(asset.Borrowed),
Free: fixedpoint.MustNewFromString(asset.Free),
Interest: fixedpoint.MustNewFromString(asset.Interest),
Locked: fixedpoint.MustNewFromString(asset.Locked),
NetAsset: fixedpoint.MustNewFromString(asset.NetAsset),
})
}
return retAssets
}
func toGlobalMarginAccount(account *binance.MarginAccount) *types.MarginAccount {
return &types.MarginAccount{
BorrowEnabled: account.BorrowEnabled,
MarginLevel: fixedpoint.MustNewFromString(account.MarginLevel),
TotalAssetOfBTC: fixedpoint.MustNewFromString(account.TotalAssetOfBTC),
TotalLiabilityOfBTC: fixedpoint.MustNewFromString(account.TotalLiabilityOfBTC),
TotalNetAssetOfBTC: fixedpoint.MustNewFromString(account.TotalNetAssetOfBTC),
TradeEnabled: account.TradeEnabled,
TransferEnabled: account.TransferEnabled,
UserAssets: toGlobalMarginUserAssets(account.UserAssets),
}
}
func toGlobalTicker(stats *binance.PriceChangeStats) types.Ticker {
return types.Ticker{
Volume: util.MustParseFloat(stats.Volume),

View File

@ -170,17 +170,27 @@ func (e *Exchange) NewStream() types.Stream {
return stream
}
func (e *Exchange) QueryMarginAccount(ctx context.Context) (*binance.MarginAccount, error) {
return e.Client.NewGetMarginAccountService().Do(ctx)
func (e *Exchange) QueryMarginAccount(ctx context.Context) (*types.MarginAccount, error) {
account, err := e.Client.NewGetMarginAccountService().Do(ctx)
if err != nil {
return nil, err
}
return toGlobalMarginAccount(account), nil
}
func (e *Exchange) QueryIsolatedMarginAccount(ctx context.Context, symbols ...string) (*binance.IsolatedMarginAccount, error) {
func (e *Exchange) QueryIsolatedMarginAccount(ctx context.Context, symbols ...string) (*types.IsolatedMarginAccount, error) {
req := e.Client.NewGetIsolatedMarginAccountService()
if len(symbols) > 0 {
req.Symbols(symbols...)
}
return req.Do(ctx)
account, err := req.Do(ctx)
if err != nil {
return nil, err
}
return toGlobalIsolatedMarginAccount(account), nil
}
func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since, until time.Time) (allWithdraws []types.Withdraw, err error) {

View File

@ -165,6 +165,14 @@ func NewFromString(input string) (Value, error) {
return NewFromFloat(v), nil
}
func MustNewFromString(input string) Value {
v, err := NewFromString(input)
if err != nil {
panic(fmt.Errorf("can not parse %s into fixedpoint, error: %s", input, err.Error()))
}
return v
}
func NewFromFloat(val float64) Value {
return Value(int64(math.Round(val * DefaultPow)))
}

View File

@ -1,5 +1,7 @@
package types
import "github.com/c9s/bbgo/pkg/fixedpoint"
type MarginExchange interface {
UseMargin()
UseIsolatedMargin(symbol string)
@ -26,3 +28,66 @@ func (e *MarginSettings) UseIsolatedMargin(symbol string) {
e.IsIsolatedMargin = true
e.IsolatedMarginSymbol = symbol
}
// MarginAccount is for the cross margin account
type MarginAccount struct {
BorrowEnabled bool `json:"borrowEnabled"`
MarginLevel fixedpoint.Value `json:"marginLevel"`
TotalAssetOfBTC fixedpoint.Value `json:"totalAssetOfBtc"`
TotalLiabilityOfBTC fixedpoint.Value `json:"totalLiabilityOfBtc"`
TotalNetAssetOfBTC fixedpoint.Value `json:"totalNetAssetOfBtc"`
TradeEnabled bool `json:"tradeEnabled"`
TransferEnabled bool `json:"transferEnabled"`
UserAssets []MarginUserAsset `json:"userAssets"./examples/binance-margin`
}
// MarginUserAsset define user assets of margin account
type MarginUserAsset struct {
Asset string `json:"asset"`
Borrowed fixedpoint.Value `json:"borrowed"`
Free fixedpoint.Value `json:"free"`
Interest fixedpoint.Value `json:"interest"`
Locked fixedpoint.Value `json:"locked"`
NetAsset fixedpoint.Value `json:"netAsset"`
}
// IsolatedMarginAccount defines isolated user assets of margin account
type IsolatedMarginAccount struct {
TotalAssetOfBTC fixedpoint.Value `json:"totalAssetOfBtc"`
TotalLiabilityOfBTC fixedpoint.Value `json:"totalLiabilityOfBtc"`
TotalNetAssetOfBTC fixedpoint.Value `json:"totalNetAssetOfBtc"`
Assets []IsolatedMarginAsset `json:"assets"`
}
// IsolatedMarginAsset defines isolated margin asset information, like margin level, liquidation price... etc
type IsolatedMarginAsset struct {
Symbol string `json:"symbol"`
QuoteAsset IsolatedUserAsset `json:"quoteAsset"`
BaseAsset IsolatedUserAsset `json:"baseAsset"`
IsolatedCreated bool `json:"isolatedCreated"`
MarginLevel fixedpoint.Value `json:"marginLevel"`
MarginLevelStatus string `json:"marginLevelStatus"`
MarginRatio fixedpoint.Value `json:"marginRatio"`
IndexPrice fixedpoint.Value `json:"indexPrice"`
LiquidatePrice fixedpoint.Value `json:"liquidatePrice"`
LiquidateRate fixedpoint.Value `json:"liquidateRate"`
TradeEnabled bool `json:"tradeEnabled"`
}
// IsolatedUserAsset defines isolated user assets of the margin account
type IsolatedUserAsset struct {
Asset string `json:"asset"`
Borrowed fixedpoint.Value `json:"borrowed"`
Free fixedpoint.Value `json:"free"`
Interest fixedpoint.Value `json:"interest"`
Locked fixedpoint.Value `json:"locked"`
NetAsset fixedpoint.Value `json:"netAsset"`
NetAssetOfBtc fixedpoint.Value `json:"netAssetOfBtc"`
BorrowEnabled bool `json:"borrowEnabled"`
RepayEnabled bool `json:"repayEnabled"`
TotalAsset fixedpoint.Value `json:"totalAsset"`
}