mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
binance: re-organize convert functions
This commit is contained in:
parent
11075b0d1a
commit
61a53947ee
|
@ -84,46 +84,6 @@ func toGlobalFuturesMarket(symbol futures.Symbol) types.Market {
|
|||
return market
|
||||
}
|
||||
|
||||
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.IsolatedMarginAssetMap) {
|
||||
retMarginAssets := make(types.IsolatedMarginAssetMap)
|
||||
for _, marginAsset := range assets {
|
||||
retMarginAssets[marginAsset.Symbol] = toGlobalIsolatedMarginAsset(marginAsset)
|
||||
}
|
||||
|
||||
return retMarginAssets
|
||||
}
|
||||
|
||||
//func toGlobalIsolatedMarginAccount(account *binance.IsolatedMarginAccount) *types.IsolatedMarginAccount {
|
||||
// return &types.IsolatedMarginAccount{
|
||||
// TotalAssetOfBTC: fixedpoint.MustNewFromString(account.TotalNetAssetOfBTC),
|
||||
|
@ -133,105 +93,6 @@ func toGlobalIsolatedMarginAssets(assets []binance.IsolatedMarginAsset) (retAsse
|
|||
// }
|
||||
//}
|
||||
|
||||
func toGlobalMarginUserAssets(assets []binance.UserAsset) types.MarginAssetMap {
|
||||
retMarginAssets := make(types.MarginAssetMap)
|
||||
for _, marginAsset := range assets {
|
||||
retMarginAssets[marginAsset.Asset] = types.MarginUserAsset{
|
||||
Asset: marginAsset.Asset,
|
||||
Borrowed: fixedpoint.MustNewFromString(marginAsset.Borrowed),
|
||||
Free: fixedpoint.MustNewFromString(marginAsset.Free),
|
||||
Interest: fixedpoint.MustNewFromString(marginAsset.Interest),
|
||||
Locked: fixedpoint.MustNewFromString(marginAsset.Locked),
|
||||
NetAsset: fixedpoint.MustNewFromString(marginAsset.NetAsset),
|
||||
}
|
||||
}
|
||||
|
||||
return retMarginAssets
|
||||
}
|
||||
|
||||
func toGlobalMarginAccountInfo(account *binance.MarginAccount) *types.MarginAccountInfo {
|
||||
return &types.MarginAccountInfo{
|
||||
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,
|
||||
Assets: toGlobalMarginUserAssets(account.UserAssets),
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalIsolatedMarginAccountInfo(account *binance.IsolatedMarginAccount) *types.IsolatedMarginAccountInfo {
|
||||
return &types.IsolatedMarginAccountInfo{
|
||||
TotalAssetOfBTC: fixedpoint.MustNewFromString(account.TotalAssetOfBTC),
|
||||
TotalLiabilityOfBTC: fixedpoint.MustNewFromString(account.TotalLiabilityOfBTC),
|
||||
TotalNetAssetOfBTC: fixedpoint.MustNewFromString(account.TotalNetAssetOfBTC),
|
||||
Assets: toGlobalIsolatedMarginAssets(account.Assets),
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalFuturesAccountInfo(account *futures.Account) *types.FuturesAccountInfo {
|
||||
return &types.FuturesAccountInfo{
|
||||
Assets: toGlobalFuturesUserAssets(account.Assets),
|
||||
Positions: toGlobalFuturesPositions(account.Positions),
|
||||
TotalInitialMargin: fixedpoint.MustNewFromString(account.TotalInitialMargin),
|
||||
TotalMaintMargin: fixedpoint.MustNewFromString(account.TotalMaintMargin),
|
||||
TotalMarginBalance: fixedpoint.MustNewFromString(account.TotalMarginBalance),
|
||||
TotalOpenOrderInitialMargin: fixedpoint.MustNewFromString(account.TotalOpenOrderInitialMargin),
|
||||
TotalPositionInitialMargin: fixedpoint.MustNewFromString(account.TotalPositionInitialMargin),
|
||||
TotalUnrealizedProfit: fixedpoint.MustNewFromString(account.TotalUnrealizedProfit),
|
||||
TotalWalletBalance: fixedpoint.MustNewFromString(account.TotalWalletBalance),
|
||||
UpdateTime: account.UpdateTime,
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalFuturesBalance(balances []*futures.Balance) types.BalanceMap {
|
||||
retBalances := make(types.BalanceMap)
|
||||
for _, balance := range balances {
|
||||
retBalances[balance.Asset] = types.Balance{
|
||||
Currency: balance.Asset,
|
||||
Available: fixedpoint.MustNewFromString(balance.AvailableBalance),
|
||||
}
|
||||
}
|
||||
return retBalances
|
||||
}
|
||||
|
||||
func toGlobalFuturesPositions(futuresPositions []*futures.AccountPosition) types.FuturesPositionMap {
|
||||
retFuturesPositions := make(types.FuturesPositionMap)
|
||||
for _, futuresPosition := range futuresPositions {
|
||||
retFuturesPositions[futuresPosition.Symbol] = types.FuturesPosition{ // TODO: types.FuturesPosition
|
||||
Isolated: futuresPosition.Isolated,
|
||||
PositionRisk: &types.PositionRisk{
|
||||
Leverage: fixedpoint.MustNewFromString(futuresPosition.Leverage),
|
||||
},
|
||||
Symbol: futuresPosition.Symbol,
|
||||
UpdateTime: futuresPosition.UpdateTime,
|
||||
}
|
||||
}
|
||||
|
||||
return retFuturesPositions
|
||||
}
|
||||
|
||||
func toGlobalFuturesUserAssets(assets []*futures.AccountAsset) (retAssets types.FuturesAssetMap) {
|
||||
retFuturesAssets := make(types.FuturesAssetMap)
|
||||
for _, futuresAsset := range assets {
|
||||
retFuturesAssets[futuresAsset.Asset] = types.FuturesUserAsset{
|
||||
Asset: futuresAsset.Asset,
|
||||
InitialMargin: fixedpoint.MustNewFromString(futuresAsset.InitialMargin),
|
||||
MaintMargin: fixedpoint.MustNewFromString(futuresAsset.MaintMargin),
|
||||
MarginBalance: fixedpoint.MustNewFromString(futuresAsset.MarginBalance),
|
||||
MaxWithdrawAmount: fixedpoint.MustNewFromString(futuresAsset.MaxWithdrawAmount),
|
||||
OpenOrderInitialMargin: fixedpoint.MustNewFromString(futuresAsset.OpenOrderInitialMargin),
|
||||
PositionInitialMargin: fixedpoint.MustNewFromString(futuresAsset.PositionInitialMargin),
|
||||
UnrealizedProfit: fixedpoint.MustNewFromString(futuresAsset.UnrealizedProfit),
|
||||
WalletBalance: fixedpoint.MustNewFromString(futuresAsset.WalletBalance),
|
||||
}
|
||||
}
|
||||
|
||||
return retFuturesAssets
|
||||
}
|
||||
|
||||
func toGlobalTicker(stats *binance.PriceChangeStats) (*types.Ticker, error) {
|
||||
return &types.Ticker{
|
||||
Volume: fixedpoint.MustNewFromString(stats.Volume),
|
||||
|
@ -267,28 +128,6 @@ func toLocalOrderType(orderType types.OrderType) (binance.OrderType, error) {
|
|||
return "", fmt.Errorf("can not convert to local order, order type %s not supported", orderType)
|
||||
}
|
||||
|
||||
func toLocalFuturesOrderType(orderType types.OrderType) (futures.OrderType, error) {
|
||||
switch orderType {
|
||||
|
||||
// case types.OrderTypeLimitMaker:
|
||||
// return futures.OrderTypeLimitMaker, nil //TODO
|
||||
|
||||
case types.OrderTypeLimit, types.OrderTypeLimitMaker:
|
||||
return futures.OrderTypeLimit, nil
|
||||
|
||||
// case types.OrderTypeStopLimit:
|
||||
// return futures.OrderTypeStopLossLimit, nil //TODO
|
||||
|
||||
// case types.OrderTypeStopMarket:
|
||||
// return futures.OrderTypeStopLoss, nil //TODO
|
||||
|
||||
case types.OrderTypeMarket:
|
||||
return futures.OrderTypeMarket, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("can not convert to local order, order type %s not supported", orderType)
|
||||
}
|
||||
|
||||
func toGlobalOrders(binanceOrders []*binance.Order) (orders []types.Order, err error) {
|
||||
for _, binanceOrder := range binanceOrders {
|
||||
order, err := toGlobalOrder(binanceOrder, false)
|
||||
|
@ -302,19 +141,6 @@ func toGlobalOrders(binanceOrders []*binance.Order) (orders []types.Order, err e
|
|||
return orders, err
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrders(futuresOrders []*futures.Order) (orders []types.Order, err error) {
|
||||
for _, futuresOrder := range futuresOrders {
|
||||
order, err := toGlobalFuturesOrder(futuresOrder, false)
|
||||
if err != nil {
|
||||
return orders, err
|
||||
}
|
||||
|
||||
orders = append(orders, *order)
|
||||
}
|
||||
|
||||
return orders, err
|
||||
}
|
||||
|
||||
func toGlobalOrder(binanceOrder *binance.Order, isMargin bool) (*types.Order, error) {
|
||||
return &types.Order{
|
||||
SubmitOrder: types.SubmitOrder{
|
||||
|
@ -338,29 +164,6 @@ func toGlobalOrder(binanceOrder *binance.Order, isMargin bool) (*types.Order, er
|
|||
}, nil
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrder(futuresOrder *futures.Order, isMargin bool) (*types.Order, error) {
|
||||
return &types.Order{
|
||||
SubmitOrder: types.SubmitOrder{
|
||||
ClientOrderID: futuresOrder.ClientOrderID,
|
||||
Symbol: futuresOrder.Symbol,
|
||||
Side: toGlobalFuturesSideType(futuresOrder.Side),
|
||||
Type: toGlobalFuturesOrderType(futuresOrder.Type),
|
||||
ReduceOnly: futuresOrder.ReduceOnly,
|
||||
ClosePosition: futuresOrder.ClosePosition,
|
||||
Quantity: fixedpoint.MustNewFromString(futuresOrder.OrigQuantity),
|
||||
Price: fixedpoint.MustNewFromString(futuresOrder.Price),
|
||||
TimeInForce: types.TimeInForce(futuresOrder.TimeInForce),
|
||||
},
|
||||
Exchange: types.ExchangeBinance,
|
||||
OrderID: uint64(futuresOrder.OrderID),
|
||||
Status: toGlobalFuturesOrderStatus(futuresOrder.Status),
|
||||
ExecutedQuantity: fixedpoint.MustNewFromString(futuresOrder.ExecutedQuantity),
|
||||
CreationTime: types.Time(millisecondTime(futuresOrder.Time)),
|
||||
UpdateTime: types.Time(millisecondTime(futuresOrder.UpdateTime)),
|
||||
IsMargin: isMargin,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func millisecondTime(t int64) time.Time {
|
||||
return time.Unix(0, t*int64(time.Millisecond))
|
||||
}
|
||||
|
@ -418,58 +221,6 @@ func toGlobalTrade(t binance.TradeV3, isMargin bool) (*types.Trade, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func toGlobalFuturesTrade(t futures.AccountTrade) (*types.Trade, error) {
|
||||
// skip trade ID that is the same. however this should not happen
|
||||
var side types.SideType
|
||||
if t.Buyer {
|
||||
side = types.SideTypeBuy
|
||||
} else {
|
||||
side = types.SideTypeSell
|
||||
}
|
||||
|
||||
price, err := fixedpoint.NewFromString(t.Price)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "price parse error, price: %+v", t.Price)
|
||||
}
|
||||
|
||||
quantity, err := fixedpoint.NewFromString(t.Quantity)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "quantity parse error, quantity: %+v", t.Quantity)
|
||||
}
|
||||
|
||||
var quoteQuantity fixedpoint.Value
|
||||
if len(t.QuoteQuantity) > 0 {
|
||||
quoteQuantity, err = fixedpoint.NewFromString(t.QuoteQuantity)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "quote quantity parse error, quoteQuantity: %+v", t.QuoteQuantity)
|
||||
}
|
||||
} else {
|
||||
quoteQuantity = price.Mul(quantity)
|
||||
}
|
||||
|
||||
fee, err := fixedpoint.NewFromString(t.Commission)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "commission parse error, commission: %+v", t.Commission)
|
||||
}
|
||||
|
||||
return &types.Trade{
|
||||
ID: uint64(t.ID),
|
||||
OrderID: uint64(t.OrderID),
|
||||
Price: price,
|
||||
Symbol: t.Symbol,
|
||||
Exchange: "binance",
|
||||
Quantity: quantity,
|
||||
QuoteQuantity: quoteQuantity,
|
||||
Side: side,
|
||||
IsBuyer: t.Buyer,
|
||||
IsMaker: t.Maker,
|
||||
Fee: fee,
|
||||
FeeCurrency: t.CommissionAsset,
|
||||
Time: types.Time(millisecondTime(t.Time)),
|
||||
IsFutures: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toGlobalSideType(side binance.SideType) types.SideType {
|
||||
switch side {
|
||||
case binance.SideTypeBuy:
|
||||
|
@ -484,20 +235,6 @@ func toGlobalSideType(side binance.SideType) types.SideType {
|
|||
}
|
||||
}
|
||||
|
||||
func toGlobalFuturesSideType(side futures.SideType) types.SideType {
|
||||
switch side {
|
||||
case futures.SideTypeBuy:
|
||||
return types.SideTypeBuy
|
||||
|
||||
case futures.SideTypeSell:
|
||||
return types.SideTypeSell
|
||||
|
||||
default:
|
||||
log.Errorf("can not convert futures side type, unknown side type: %q", side)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalOrderType(orderType binance.OrderType) types.OrderType {
|
||||
switch orderType {
|
||||
|
||||
|
@ -520,27 +257,6 @@ func toGlobalOrderType(orderType binance.OrderType) types.OrderType {
|
|||
}
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrderType(orderType futures.OrderType) types.OrderType {
|
||||
switch orderType {
|
||||
// TODO
|
||||
case futures.OrderTypeLimit: // , futures.OrderTypeLimitMaker, futures.OrderTypeTakeProfitLimit:
|
||||
return types.OrderTypeLimit
|
||||
|
||||
case futures.OrderTypeMarket:
|
||||
return types.OrderTypeMarket
|
||||
// TODO
|
||||
// case futures.OrderTypeStopLossLimit:
|
||||
// return types.OrderTypeStopLimit
|
||||
// TODO
|
||||
// case futures.OrderTypeStopLoss:
|
||||
// return types.OrderTypeStopMarket
|
||||
|
||||
default:
|
||||
log.Errorf("unsupported order type: %v", orderType)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalOrderStatus(orderStatus binance.OrderStatusType) types.OrderStatus {
|
||||
switch orderStatus {
|
||||
case binance.OrderStatusTypeNew:
|
||||
|
@ -562,27 +278,6 @@ func toGlobalOrderStatus(orderStatus binance.OrderStatusType) types.OrderStatus
|
|||
return types.OrderStatus(orderStatus)
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrderStatus(orderStatus futures.OrderStatusType) types.OrderStatus {
|
||||
switch orderStatus {
|
||||
case futures.OrderStatusTypeNew:
|
||||
return types.OrderStatusNew
|
||||
|
||||
case futures.OrderStatusTypeRejected:
|
||||
return types.OrderStatusRejected
|
||||
|
||||
case futures.OrderStatusTypeCanceled:
|
||||
return types.OrderStatusCanceled
|
||||
|
||||
case futures.OrderStatusTypePartiallyFilled:
|
||||
return types.OrderStatusPartiallyFilled
|
||||
|
||||
case futures.OrderStatusTypeFilled:
|
||||
return types.OrderStatusFilled
|
||||
}
|
||||
|
||||
return types.OrderStatus(orderStatus)
|
||||
}
|
||||
|
||||
func convertSubscription(s types.Subscription) string {
|
||||
// binance uses lower case symbol name,
|
||||
// for kline, it's "<symbol>@kline_<interval>"
|
||||
|
@ -623,42 +318,3 @@ func convertSubscription(s types.Subscription) string {
|
|||
return fmt.Sprintf("%s@%s", strings.ToLower(s.Symbol), s.Channel)
|
||||
}
|
||||
|
||||
func convertPremiumIndex(index *futures.PremiumIndex) (*types.PremiumIndex, error) {
|
||||
markPrice, err := fixedpoint.NewFromString(index.MarkPrice)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lastFundingRate, err := fixedpoint.NewFromString(index.LastFundingRate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nextFundingTime := time.Unix(0, index.NextFundingTime*int64(time.Millisecond))
|
||||
t := time.Unix(0, index.Time*int64(time.Millisecond))
|
||||
|
||||
return &types.PremiumIndex{
|
||||
Symbol: index.Symbol,
|
||||
MarkPrice: markPrice,
|
||||
NextFundingTime: nextFundingTime,
|
||||
LastFundingRate: lastFundingRate,
|
||||
Time: t,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertPositionRisk(risk *futures.PositionRisk) (*types.PositionRisk, error) {
|
||||
leverage, err := fixedpoint.NewFromString(risk.Leverage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
liquidationPrice, err := fixedpoint.NewFromString(risk.LiquidationPrice)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.PositionRisk{
|
||||
Leverage: leverage,
|
||||
LiquidationPrice: liquidationPrice,
|
||||
}, nil
|
||||
}
|
||||
|
|
279
pkg/exchange/binance/convert_futures.go
Normal file
279
pkg/exchange/binance/convert_futures.go
Normal file
|
@ -0,0 +1,279 @@
|
|||
package binance
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/adshao/go-binance/v2/futures"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
func toGlobalFuturesAccountInfo(account *futures.Account) *types.FuturesAccountInfo {
|
||||
return &types.FuturesAccountInfo{
|
||||
Assets: toGlobalFuturesUserAssets(account.Assets),
|
||||
Positions: toGlobalFuturesPositions(account.Positions),
|
||||
TotalInitialMargin: fixedpoint.MustNewFromString(account.TotalInitialMargin),
|
||||
TotalMaintMargin: fixedpoint.MustNewFromString(account.TotalMaintMargin),
|
||||
TotalMarginBalance: fixedpoint.MustNewFromString(account.TotalMarginBalance),
|
||||
TotalOpenOrderInitialMargin: fixedpoint.MustNewFromString(account.TotalOpenOrderInitialMargin),
|
||||
TotalPositionInitialMargin: fixedpoint.MustNewFromString(account.TotalPositionInitialMargin),
|
||||
TotalUnrealizedProfit: fixedpoint.MustNewFromString(account.TotalUnrealizedProfit),
|
||||
TotalWalletBalance: fixedpoint.MustNewFromString(account.TotalWalletBalance),
|
||||
UpdateTime: account.UpdateTime,
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalFuturesBalance(balances []*futures.Balance) types.BalanceMap {
|
||||
retBalances := make(types.BalanceMap)
|
||||
for _, balance := range balances {
|
||||
retBalances[balance.Asset] = types.Balance{
|
||||
Currency: balance.Asset,
|
||||
Available: fixedpoint.MustNewFromString(balance.AvailableBalance),
|
||||
}
|
||||
}
|
||||
return retBalances
|
||||
}
|
||||
|
||||
func toGlobalFuturesPositions(futuresPositions []*futures.AccountPosition) types.FuturesPositionMap {
|
||||
retFuturesPositions := make(types.FuturesPositionMap)
|
||||
for _, futuresPosition := range futuresPositions {
|
||||
retFuturesPositions[futuresPosition.Symbol] = types.FuturesPosition{ // TODO: types.FuturesPosition
|
||||
Isolated: futuresPosition.Isolated,
|
||||
PositionRisk: &types.PositionRisk{
|
||||
Leverage: fixedpoint.MustNewFromString(futuresPosition.Leverage),
|
||||
},
|
||||
Symbol: futuresPosition.Symbol,
|
||||
UpdateTime: futuresPosition.UpdateTime,
|
||||
}
|
||||
}
|
||||
|
||||
return retFuturesPositions
|
||||
}
|
||||
|
||||
func toGlobalFuturesUserAssets(assets []*futures.AccountAsset) (retAssets types.FuturesAssetMap) {
|
||||
retFuturesAssets := make(types.FuturesAssetMap)
|
||||
for _, futuresAsset := range assets {
|
||||
retFuturesAssets[futuresAsset.Asset] = types.FuturesUserAsset{
|
||||
Asset: futuresAsset.Asset,
|
||||
InitialMargin: fixedpoint.MustNewFromString(futuresAsset.InitialMargin),
|
||||
MaintMargin: fixedpoint.MustNewFromString(futuresAsset.MaintMargin),
|
||||
MarginBalance: fixedpoint.MustNewFromString(futuresAsset.MarginBalance),
|
||||
MaxWithdrawAmount: fixedpoint.MustNewFromString(futuresAsset.MaxWithdrawAmount),
|
||||
OpenOrderInitialMargin: fixedpoint.MustNewFromString(futuresAsset.OpenOrderInitialMargin),
|
||||
PositionInitialMargin: fixedpoint.MustNewFromString(futuresAsset.PositionInitialMargin),
|
||||
UnrealizedProfit: fixedpoint.MustNewFromString(futuresAsset.UnrealizedProfit),
|
||||
WalletBalance: fixedpoint.MustNewFromString(futuresAsset.WalletBalance),
|
||||
}
|
||||
}
|
||||
|
||||
return retFuturesAssets
|
||||
}
|
||||
|
||||
func toLocalFuturesOrderType(orderType types.OrderType) (futures.OrderType, error) {
|
||||
switch orderType {
|
||||
|
||||
// case types.OrderTypeLimitMaker:
|
||||
// return futures.OrderTypeLimitMaker, nil //TODO
|
||||
|
||||
case types.OrderTypeLimit, types.OrderTypeLimitMaker:
|
||||
return futures.OrderTypeLimit, nil
|
||||
|
||||
// case types.OrderTypeStopLimit:
|
||||
// return futures.OrderTypeStopLossLimit, nil //TODO
|
||||
|
||||
// case types.OrderTypeStopMarket:
|
||||
// return futures.OrderTypeStopLoss, nil //TODO
|
||||
|
||||
case types.OrderTypeMarket:
|
||||
return futures.OrderTypeMarket, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("can not convert to local order, order type %s not supported", orderType)
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrders(futuresOrders []*futures.Order) (orders []types.Order, err error) {
|
||||
for _, futuresOrder := range futuresOrders {
|
||||
order, err := toGlobalFuturesOrder(futuresOrder, false)
|
||||
if err != nil {
|
||||
return orders, err
|
||||
}
|
||||
|
||||
orders = append(orders, *order)
|
||||
}
|
||||
|
||||
return orders, err
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrder(futuresOrder *futures.Order, isMargin bool) (*types.Order, error) {
|
||||
return &types.Order{
|
||||
SubmitOrder: types.SubmitOrder{
|
||||
ClientOrderID: futuresOrder.ClientOrderID,
|
||||
Symbol: futuresOrder.Symbol,
|
||||
Side: toGlobalFuturesSideType(futuresOrder.Side),
|
||||
Type: toGlobalFuturesOrderType(futuresOrder.Type),
|
||||
ReduceOnly: futuresOrder.ReduceOnly,
|
||||
ClosePosition: futuresOrder.ClosePosition,
|
||||
Quantity: fixedpoint.MustNewFromString(futuresOrder.OrigQuantity),
|
||||
Price: fixedpoint.MustNewFromString(futuresOrder.Price),
|
||||
TimeInForce: types.TimeInForce(futuresOrder.TimeInForce),
|
||||
},
|
||||
Exchange: types.ExchangeBinance,
|
||||
OrderID: uint64(futuresOrder.OrderID),
|
||||
Status: toGlobalFuturesOrderStatus(futuresOrder.Status),
|
||||
ExecutedQuantity: fixedpoint.MustNewFromString(futuresOrder.ExecutedQuantity),
|
||||
CreationTime: types.Time(millisecondTime(futuresOrder.Time)),
|
||||
UpdateTime: types.Time(millisecondTime(futuresOrder.UpdateTime)),
|
||||
IsMargin: isMargin,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toGlobalFuturesTrade(t futures.AccountTrade) (*types.Trade, error) {
|
||||
// skip trade ID that is the same. however this should not happen
|
||||
var side types.SideType
|
||||
if t.Buyer {
|
||||
side = types.SideTypeBuy
|
||||
} else {
|
||||
side = types.SideTypeSell
|
||||
}
|
||||
|
||||
price, err := fixedpoint.NewFromString(t.Price)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "price parse error, price: %+v", t.Price)
|
||||
}
|
||||
|
||||
quantity, err := fixedpoint.NewFromString(t.Quantity)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "quantity parse error, quantity: %+v", t.Quantity)
|
||||
}
|
||||
|
||||
var quoteQuantity fixedpoint.Value
|
||||
if len(t.QuoteQuantity) > 0 {
|
||||
quoteQuantity, err = fixedpoint.NewFromString(t.QuoteQuantity)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "quote quantity parse error, quoteQuantity: %+v", t.QuoteQuantity)
|
||||
}
|
||||
} else {
|
||||
quoteQuantity = price.Mul(quantity)
|
||||
}
|
||||
|
||||
fee, err := fixedpoint.NewFromString(t.Commission)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "commission parse error, commission: %+v", t.Commission)
|
||||
}
|
||||
|
||||
return &types.Trade{
|
||||
ID: uint64(t.ID),
|
||||
OrderID: uint64(t.OrderID),
|
||||
Price: price,
|
||||
Symbol: t.Symbol,
|
||||
Exchange: "binance",
|
||||
Quantity: quantity,
|
||||
QuoteQuantity: quoteQuantity,
|
||||
Side: side,
|
||||
IsBuyer: t.Buyer,
|
||||
IsMaker: t.Maker,
|
||||
Fee: fee,
|
||||
FeeCurrency: t.CommissionAsset,
|
||||
Time: types.Time(millisecondTime(t.Time)),
|
||||
IsFutures: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toGlobalFuturesSideType(side futures.SideType) types.SideType {
|
||||
switch side {
|
||||
case futures.SideTypeBuy:
|
||||
return types.SideTypeBuy
|
||||
|
||||
case futures.SideTypeSell:
|
||||
return types.SideTypeSell
|
||||
|
||||
default:
|
||||
log.Errorf("can not convert futures side type, unknown side type: %q", side)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrderType(orderType futures.OrderType) types.OrderType {
|
||||
switch orderType {
|
||||
// TODO
|
||||
case futures.OrderTypeLimit: // , futures.OrderTypeLimitMaker, futures.OrderTypeTakeProfitLimit:
|
||||
return types.OrderTypeLimit
|
||||
|
||||
case futures.OrderTypeMarket:
|
||||
return types.OrderTypeMarket
|
||||
// TODO
|
||||
// case futures.OrderTypeStopLossLimit:
|
||||
// return types.OrderTypeStopLimit
|
||||
// TODO
|
||||
// case futures.OrderTypeStopLoss:
|
||||
// return types.OrderTypeStopMarket
|
||||
|
||||
default:
|
||||
log.Errorf("unsupported order type: %v", orderType)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalFuturesOrderStatus(orderStatus futures.OrderStatusType) types.OrderStatus {
|
||||
switch orderStatus {
|
||||
case futures.OrderStatusTypeNew:
|
||||
return types.OrderStatusNew
|
||||
|
||||
case futures.OrderStatusTypeRejected:
|
||||
return types.OrderStatusRejected
|
||||
|
||||
case futures.OrderStatusTypeCanceled:
|
||||
return types.OrderStatusCanceled
|
||||
|
||||
case futures.OrderStatusTypePartiallyFilled:
|
||||
return types.OrderStatusPartiallyFilled
|
||||
|
||||
case futures.OrderStatusTypeFilled:
|
||||
return types.OrderStatusFilled
|
||||
}
|
||||
|
||||
return types.OrderStatus(orderStatus)
|
||||
}
|
||||
|
||||
func convertPremiumIndex(index *futures.PremiumIndex) (*types.PremiumIndex, error) {
|
||||
markPrice, err := fixedpoint.NewFromString(index.MarkPrice)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lastFundingRate, err := fixedpoint.NewFromString(index.LastFundingRate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nextFundingTime := time.Unix(0, index.NextFundingTime*int64(time.Millisecond))
|
||||
t := time.Unix(0, index.Time*int64(time.Millisecond))
|
||||
|
||||
return &types.PremiumIndex{
|
||||
Symbol: index.Symbol,
|
||||
MarkPrice: markPrice,
|
||||
NextFundingTime: nextFundingTime,
|
||||
LastFundingRate: lastFundingRate,
|
||||
Time: t,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertPositionRisk(risk *futures.PositionRisk) (*types.PositionRisk, error) {
|
||||
leverage, err := fixedpoint.NewFromString(risk.Leverage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
liquidationPrice, err := fixedpoint.NewFromString(risk.LiquidationPrice)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.PositionRisk{
|
||||
Leverage: leverage,
|
||||
LiquidationPrice: liquidationPrice,
|
||||
}, nil
|
||||
}
|
119
pkg/exchange/binance/convert_margin.go
Normal file
119
pkg/exchange/binance/convert_margin.go
Normal file
|
@ -0,0 +1,119 @@
|
|||
package binance
|
||||
|
||||
import (
|
||||
"github.com/adshao/go-binance/v2"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/exchange/binance/binanceapi"
|
||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
func toGlobalLoan(record binanceapi.MarginLoanRecord) types.MarginLoanRecord {
|
||||
return types.MarginLoanRecord{
|
||||
TransactionID: uint64(record.TxId),
|
||||
Asset: record.Asset,
|
||||
Principle: record.Principal,
|
||||
Time: types.Time(record.Timestamp),
|
||||
IsolatedSymbol: record.IsolatedSymbol,
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalRepay(record binanceapi.MarginRepayRecord) types.MarginRepayRecord {
|
||||
return types.MarginRepayRecord{
|
||||
TransactionID: record.TxId,
|
||||
Asset: record.Asset,
|
||||
Principle: record.Principal,
|
||||
Time: types.Time(record.Timestamp),
|
||||
IsolatedSymbol: record.IsolatedSymbol,
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalInterest(record binanceapi.MarginInterest) types.MarginInterest {
|
||||
return types.MarginInterest{
|
||||
Asset: record.Asset,
|
||||
Principle: record.Principal,
|
||||
Interest: record.Interest,
|
||||
InterestRate: record.InterestRate,
|
||||
IsolatedSymbol: record.IsolatedSymbol,
|
||||
Time: types.Time(record.InterestAccuredTime),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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.IsolatedMarginAssetMap) {
|
||||
retMarginAssets := make(types.IsolatedMarginAssetMap)
|
||||
for _, marginAsset := range assets {
|
||||
retMarginAssets[marginAsset.Symbol] = toGlobalIsolatedMarginAsset(marginAsset)
|
||||
}
|
||||
|
||||
return retMarginAssets
|
||||
}
|
||||
|
||||
func toGlobalMarginUserAssets(assets []binance.UserAsset) types.MarginAssetMap {
|
||||
retMarginAssets := make(types.MarginAssetMap)
|
||||
for _, marginAsset := range assets {
|
||||
retMarginAssets[marginAsset.Asset] = types.MarginUserAsset{
|
||||
Asset: marginAsset.Asset,
|
||||
Borrowed: fixedpoint.MustNewFromString(marginAsset.Borrowed),
|
||||
Free: fixedpoint.MustNewFromString(marginAsset.Free),
|
||||
Interest: fixedpoint.MustNewFromString(marginAsset.Interest),
|
||||
Locked: fixedpoint.MustNewFromString(marginAsset.Locked),
|
||||
NetAsset: fixedpoint.MustNewFromString(marginAsset.NetAsset),
|
||||
}
|
||||
}
|
||||
|
||||
return retMarginAssets
|
||||
}
|
||||
|
||||
func toGlobalMarginAccountInfo(account *binance.MarginAccount) *types.MarginAccountInfo {
|
||||
return &types.MarginAccountInfo{
|
||||
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,
|
||||
Assets: toGlobalMarginUserAssets(account.UserAssets),
|
||||
}
|
||||
}
|
||||
|
||||
func toGlobalIsolatedMarginAccountInfo(account *binance.IsolatedMarginAccount) *types.IsolatedMarginAccountInfo {
|
||||
return &types.IsolatedMarginAccountInfo{
|
||||
TotalAssetOfBTC: fixedpoint.MustNewFromString(account.TotalAssetOfBTC),
|
||||
TotalLiabilityOfBTC: fixedpoint.MustNewFromString(account.TotalLiabilityOfBTC),
|
||||
TotalNetAssetOfBTC: fixedpoint.MustNewFromString(account.TotalNetAssetOfBTC),
|
||||
Assets: toGlobalIsolatedMarginAssets(account.Assets),
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/exchange/binance/binanceapi"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
|
@ -51,16 +50,6 @@ func (e *Exchange) QueryLoanHistory(ctx context.Context, asset string, startTime
|
|||
return loans, err
|
||||
}
|
||||
|
||||
func toGlobalLoan(record binanceapi.MarginLoanRecord) types.MarginLoanRecord {
|
||||
return types.MarginLoanRecord{
|
||||
TransactionID: uint64(record.TxId),
|
||||
Asset: record.Asset,
|
||||
Principle: record.Principal,
|
||||
Time: types.Time(record.Timestamp),
|
||||
IsolatedSymbol: record.IsolatedSymbol,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Exchange) QueryRepayHistory(ctx context.Context, asset string, startTime, endTime *time.Time) ([]types.MarginRepayRecord, error) {
|
||||
req := e.client2.NewGetMarginRepayHistoryRequest()
|
||||
req.Asset(asset)
|
||||
|
@ -101,16 +90,6 @@ func (e *Exchange) QueryRepayHistory(ctx context.Context, asset string, startTim
|
|||
return repays, err
|
||||
}
|
||||
|
||||
func toGlobalRepay(record binanceapi.MarginRepayRecord) types.MarginRepayRecord {
|
||||
return types.MarginRepayRecord{
|
||||
TransactionID: record.TxId,
|
||||
Asset: record.Asset,
|
||||
Principle: record.Principal,
|
||||
Time: types.Time(record.Timestamp),
|
||||
IsolatedSymbol: record.IsolatedSymbol,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Exchange) QueryLiquidationHistory(ctx context.Context, startTime, endTime *time.Time) ([]types.MarginLiquidationRecord, error) {
|
||||
req := e.client2.NewGetMarginLiquidationHistoryRequest()
|
||||
|
||||
|
@ -172,14 +151,3 @@ func (e *Exchange) QueryInterestHistory(ctx context.Context, asset string, start
|
|||
return interests, err
|
||||
}
|
||||
|
||||
func toGlobalInterest(record binanceapi.MarginInterest) types.MarginInterest {
|
||||
return types.MarginInterest{
|
||||
Asset: record.Asset,
|
||||
Principle: record.Principal,
|
||||
Interest: record.Interest,
|
||||
InterestRate: record.InterestRate,
|
||||
IsolatedSymbol: record.IsolatedSymbol,
|
||||
Time: types.Time(record.InterestAccuredTime),
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user