package trade import ( "encoding/json" "errors" "log" "strings" "git.apinb.com/bsm-sdk/core/utils" "git.apinb.com/quant/strategy/internal/core/market" "github.com/bitget-golang/sdk-api/config" bitget "github.com/bitget-golang/sdk-api/pkg/client/v2" ) type BitgetClient struct { LastUPL map[string]float64 AccountClient *bitget.MixAccountClient MarketClient *bitget.MixMarketClient OrderClient *bitget.MixOrderClient } type SymbolResp struct { Code string `json:"code"` Data []SymbolDataResp `json:"data"` Msg string `json:"msg"` RequestTime int64 `json:"requestTime"` } type SymbolDataResp struct { BaseCoin string `json:"baseCoin"` BuyLimitPriceRatio string `json:"buyLimitPriceRatio"` DeliveryStartTime string `json:"deliveryStartTime"` DeliveryTime string `json:"deliveryTime"` FeeRateUpRatio string `json:"feeRateUpRatio"` FundInterval string `json:"fundInterval"` LaunchTime string `json:"launchTime"` LimitOpenTime string `json:"limitOpenTime"` MaintainTime string `json:"maintainTime"` MakerFeeRate string `json:"makerFeeRate"` MaxLever string `json:"maxLever"` MaxPositionNum string `json:"maxPositionNum"` MaxProductOrderNum string `json:"maxProductOrderNum"` MaxSymbolOrderNum string `json:"maxSymbolOrderNum"` MinLever string `json:"minLever"` MinTradeNum string `json:"minTradeNum"` MinTradeUSDT string `json:"minTradeUSDT"` OffTime string `json:"offTime"` OpenCostUpRatio string `json:"openCostUpRatio"` PosLimit string `json:"posLimit"` PriceEndStep string `json:"priceEndStep"` PricePlace string `json:"pricePlace"` QuoteCoin string `json:"quoteCoin"` SellLimitPriceRatio string `json:"sellLimitPriceRatio"` SizeMultiplier string `json:"sizeMultiplier"` SupportMarginCoins []string `json:"supportMarginCoins"` Symbol string `json:"symbol"` SymbolStatus string `json:"symbolStatus"` SymbolType string `json:"symbolType"` TakerFeeRate string `json:"takerFeeRate"` VolumePlace string `json:"volumePlace"` } type AccountsResp struct { Code string `json:"code"` Data []struct { MarginCoin string `json:"marginCoin"` Locked string `json:"locked"` Available string `json:"available"` CrossedMaxAvailable string `json:"crossedMaxAvailable"` IsolatedMaxAvailable string `json:"isolatedMaxAvailable"` MaxTransferOut string `json:"maxTransferOut"` AccountEquity string `json:"accountEquity"` UsdtEquity string `json:"usdtEquity"` BtcEquity string `json:"btcEquity"` CrossedRiskRate string `json:"crossedRiskRate"` UnrealizedPL string `json:"unrealizedPL"` Coupon string `json:"coupon"` UnionTotalMagin string `json:"unionTotalMagin"` UnionAvailable string `json:"unionAvailable"` UnionMm string `json:"unionMm"` AssetList []struct { Coin string `json:"coin"` Balance string `json:"balance"` Available string `json:"available"` } `json:"assetList"` IsolatedMargin string `json:"isolatedMargin"` CrossedMargin string `json:"crossedMargin"` CrossedUnrealizedPL string `json:"crossedUnrealizedPL"` IsolatedUnrealizedPL string `json:"isolatedUnrealizedPL"` AssetMode string `json:"assetMode"` } `json:"data"` Msg string `json:"msg"` RequestTime int64 `json:"requestTime"` } type AllPositionResp struct { Code string `json:"code"` Data []*BitgetPositionData `json:"data"` Msg string `json:"msg"` RequestTime int64 `json:"requestTime"` } type BitgetPositionData struct { AchievedProfits string `json:"achievedProfits"` Available string `json:"available"` BreakEvenPrice string `json:"breakEvenPrice"` CTime string `json:"cTime"` DeductedFee string `json:"deductedFee"` HoldSide string `json:"holdSide"` KeepMarginRate string `json:"keepMarginRate"` Leverage string `json:"leverage"` LiquidationPrice string `json:"liquidationPrice"` Locked string `json:"locked"` MarginCoin string `json:"marginCoin"` MarginMode string `json:"marginMode"` MarginRatio string `json:"marginRatio"` MarginSize string `json:"marginSize"` MarkPrice string `json:"markPrice"` OpenDelegateSize string `json:"openDelegateSize"` OpenPriceAvg string `json:"openPriceAvg"` PosMode string `json:"posMode"` Symbol string `json:"symbol"` Total string `json:"total"` TotalFee string `json:"totalFee"` UnrealizedPL string `json:"unrealizedPL"` UnrealizedPLR string `json:"unrealizedPLR"` } type RespMapString struct { Code string `json:"code"` Data []map[string]string `json:"data"` Msg string `json:"msg"` RequestTime int64 `json:"requestTime"` } func NewBitgetClient(apiKey, apiSecret, passphrase string) *BitgetClient { bg := &BitgetClient{ LastUPL: make(map[string]float64), } config.ApiKey = apiKey config.SecretKey = apiSecret config.PASSPHRASE = passphrase config.BaseUrl = "https://api.bitget.com" config.WsUrl = "wss://ws.bitget.com/v2/ws/private" bg.AccountClient = new(bitget.MixAccountClient).Init() bg.AccountClient.BitgetRestClient.ApiKey = config.ApiKey bg.AccountClient.BitgetRestClient.ApiSecretKey = config.SecretKey bg.AccountClient.BitgetRestClient.Passphrase = config.PASSPHRASE bg.MarketClient = new(bitget.MixMarketClient).Init() bg.MarketClient.BitgetRestClient.ApiKey = config.ApiKey bg.MarketClient.BitgetRestClient.ApiSecretKey = config.SecretKey bg.MarketClient.BitgetRestClient.Passphrase = config.PASSPHRASE bg.OrderClient = new(bitget.MixOrderClient).Init() bg.OrderClient.BitgetRestClient.ApiKey = config.ApiKey bg.OrderClient.BitgetRestClient.ApiSecretKey = config.SecretKey bg.OrderClient.BitgetRestClient.Passphrase = config.PASSPHRASE Info("BitgetClient init ok") return bg } func (bg *BitgetClient) GetFuturesAccountBalance() (string, map[string]*AccountsBalance, error) { args := map[string]string{"productType": "USDT-FUTURES"} res, err := bg.AccountClient.Accounts(args) if err != nil { return res, nil, err } // assets, _ := json.Marshal(res.Assets) // log.Println("==>", string(assets)) var acResp AccountsResp err = json.Unmarshal([]byte(res), &acResp) if err != nil { return res, nil, err } if acResp.Code != "00000" { return res, nil, errors.New(acResp.Msg) } ac := make(map[string]*AccountsBalance) for _, v := range acResp.Data { ac[strings.ToUpper(v.MarginCoin)] = &AccountsBalance{ AccountEquity: utils.String2Float64(v.AccountEquity), Available: utils.String2Float64(v.Available), } } return res, ac, nil } func (bg *BitgetClient) GetSymbolSetting(cli *bitget.MixMarketClient, symbols []string) (map[string]*market.PairSetting, error) { args := map[string]string{ "productType": "USDT-FUTURES", } resp, err := bg.MarketClient.Contracts(args) if err != nil { return nil, err } var reply SymbolResp json.Unmarshal([]byte(resp), &reply) if err != nil { return nil, err } if len(reply.Data) == 0 { return nil, errors.New("data is empty") } data := make(map[string]*market.PairSetting) for _, item := range reply.Data { if utils.ArrayInString(item.Symbol, symbols) { data[item.Symbol] = &market.PairSetting{ Symbol: item.Symbol, BaseAssetPrecision: 0, QuantityPrecision: utils.String2Int(item.VolumePlace), PricePrecision: utils.String2Int(item.PricePlace), MinTradeNum: utils.String2Float64(item.MinTradeNum), MinNotional: utils.String2Float64(item.MinTradeUSDT), Commit: item.MaxLever, } } } return data, nil } func (bg *BitgetClient) SetLeverage(symbol string, leve string) { args := map[string]string{ "productType": "USDT-FUTURES", "marginCoin": "USDT", "symbol": symbol, "leverage": leve, } _, err := bg.AccountClient.SetLeverage(args) if err != nil { panic(err) } log.Println("[INFO]", symbol, "SetLeverage:", leve) } // 获取交易对价格,限速规则: 20次/1s (IP) func (bg *BitgetClient) GetSymbolPrice(symbol string) (map[string]string, error) { args := map[string]string{ "productType": "USDT-FUTURES", "symbol": symbol, } resp, err := bg.MarketClient.SymbolPrice(args) if err != nil { return nil, err } var reply RespMapString json.Unmarshal([]byte(resp), &reply) if err != nil { return nil, err } if reply.Code != "00000" { return nil, errors.New(reply.Msg) } return reply.Data[0], nil }