GithubHelp home page GithubHelp logo

hirokisan / bybit Goto Github PK

View Code? Open in Web Editor NEW
89.0 4.0 57.0 733 KB

Bybit client library for Go

Home Page: https://pkg.go.dev/github.com/hirokisan/bybit/v2

License: MIT License

Go 99.00% Makefile 1.00%
bybit-api github go golang trading bybit-api-client bybit-go bybit-websocket

bybit's Introduction

Go Report Card golangci-lint test

bybit

bybit is an bybit client for the Go programming language.

Usage

REST API

import "github.com/hirokisan/bybit/v2"

client := bybit.NewClient().WithAuth("your api key", "your api secret")
res, err := client.Future().InversePerpetual().Balance(bybit.CoinBTC)
// do as you want

WebSocket API

for single use

import "github.com/hirokisan/bybit/v2"

wsClient := bybit.NewWebsocketClient()
svc, err := wsClient.Spot().V1().PublicV1()
if err != nil {
	return err
}
_, err = svc.SubscribeTrade(bybit.SymbolSpotBTCUSDT, func(response bybit.SpotWebsocketV1PublicV1TradeResponse) error {
	// do as you want
})
if err != nil {
	return err
}
svc.Start(context.Background())

for multiple use

import "github.com/hirokisan/bybit/v2"

wsClient := bybit.NewWebsocketClient()

executors := []bybit.WebsocketExecutor{}

svcRoot := wsClient.Spot().V1()
{
	svc, err := svcRoot.PublicV1()
	if err != nil {
		return err
	}
	_, err = svc.SubscribeTrade(bybit.SymbolSpotBTCUSDT, func(response bybit.SpotWebsocketV1PublicV1TradeResponse) error {
		// do as you want
	})
	if err != nil {
		return err
	}
	executors = append(executors, svc)
}
{
	svc, err := svcRoot.PublicV2()
	if err != nil {
		return err
	}
	_, err = svc.SubscribeTrade(bybit.SymbolSpotBTCUSDT, func(response bybit.SpotWebsocketV1PublicV2TradeResponse) error {
		// do as you want
	})
	if err != nil {
		return err
	}
	executors = append(executors, svc)
}

wsClient.Start(context.Background(), executors)

V5 usage

import "github.com/hirokisan/bybit/v2"

wsClient := bybit.NewWebsocketClient().WithBaseURL("wss://stream-testnet.bybit.com").WithAuth("key", "secret")
svc, err := wsClient.V5().Private()
if err != nil {
	// handle dialing error
}

err = svc.Subscribe()
if err != nil {
	// handle subscription error
}

err = svc.SubscribePosition(func(position bybit.V5WebsocketPrivatePositionResponse) error {
	// handle new position information
})
if err != nil {
	// handle registration error
}

errHandler := func(isWebsocketClosed bool, err error) {
	// Connection issue (timeout, etc.).

	// At this point, the connection is dead and you must handle the reconnection yourself
}

err = svc.Start(context.Background(), errHandler)
if err != nil {
	// handle reconnection (ping issue, etc.). Probably can be ignored as the errHandler would be notified too
}

Implemented

The following API endpoints have been implemented

REST API V5

Market

Position

Order

Account

Asset

User

REST API

Market Data Endpoints
  • /derivatives/v3/public/order-book/L2 Get Order Book
  • /derivatives/v3/public/kline Get Kline
  • /derivatives/v3/public/tickers Get Latest Information For Symbol
  • /derivatives/v3/public/instruments-info Get Instrument Info
  • /derivatives/v3/public/mark-price-kline Get Mark Price Kline
  • /derivatives/v3/public/index-price-kline Get Index Price Kline
Market Data Endpoints
  • /derivatives/v3/public/order-book/L2 Get Order Book
  • /derivatives/v3/public/kline Get Kline
  • /derivatives/v3/public/tickers Get Latest Information For Symbol
  • /derivatives/v3/public/instruments-info Get Instrument Info
  • /derivatives/v3/public/mark-price-kline Get Mark Price Kline
  • /derivatives/v3/public/index-price-kline Get Index Price Kline
Market Data Endpoints
  • /v2/public/orderBook/L2 Order Book
  • /v2/public/kline/list Query Kline
  • /v2/public/tickers Latest Information for Symbol
  • /v2/public/trading-records Public Trading Records
  • /v2/public/symbols Query Symbol
  • /v2/public/mark-price-kline Query Mark Price Kline
  • /v2/public/index-price-kline Query Index Price Kline
  • /v2/public/premium-index-kline Query Premium Index Kline
  • /v2/public/open-interest Open Interest
  • /v2/public/big-deal Latest Big Deal
  • /v2/public/account-ratio Long-Short Ratio
Account Data Endpoints
  • /v2/private/order/create Place Active Order
  • /v2/private/order/list Get Active Order
  • /v2/private/order/cancel Cancel Active Order
  • /v2/private/order/cancelAll Cancel All Active Orders
  • /v2/private/order Query Active Order (real-time)
  • /v2/private/stop-order/create Place Conditional Order
  • /v2/private/stop-order/list Get Conditional Order
  • /v2/private/stop-order/cancel Cancel Conditional Order
  • /v2/private/stop-order/cancelAll Cancel All Conditional Orders
  • /v2/private/stop-order Query Conditional Order (real-time)
  • /v2/private/position/list My Position
  • /v2/private/position/trading-stop Set Trading-Stop
  • /v2/private/position/leverage/save Set Leverage
  • /v2/private/account/api-key API Key info
Wallet Data Endpoints
  • /v2/private/wallet/balance Get Wallet Balance
Market Data Endpoints
  • /v2/public/orderBook/L2 Order Book
  • /public/linear/kline Query Kline
  • /v2/public/tickers Latest Information for Symbol
  • /v2/public/symbols Query Symbol
  • /v2/public/open-interest Open Interest
  • /v2/public/big-deal Latest Big Deal
  • /v2/public/account-ratio Long-Short Ratio
Account Data Endpoints
  • /private/linear/order/create Place Active Order
  • /private/linear/order/list Get Active Order
  • /private/linear/order/cancel Cancel Active Order
  • /private/linear/order/cancel-all Cancel All Active Orders
  • /private/linear/order/replace Replace Active Order
  • /private/linear/order/search Query Active Order (real-time)
  • /private/linear/stop-order/create Place Conditional Order
  • /private/linear/stop-order/list Get Conditional Order
  • /private/linear/stop-order/cancel Cancel Conditional Order
  • /private/linear/stop-order/cancel-all Cancel All Conditional Orders
  • /private/linear/stop-order/search Query Conditional Order (real-time)
  • /private/linear/position/list My Position
  • /private/linear/position/set-leverage Set Leverage
  • /private/linear/position/trading-stop Set Trading-Stop
  • /private/linear/trade/execution/list User Trade Records
  • /v2/private/account/api-key API Key info
Wallet Data Endpoints
  • /v2/private/wallet/balance Get Wallet Balance
Market Data Endpoints
  • /v2/public/orderBook/L2 Order Book
  • /v2/public/kline/list Query Kline
  • /v2/public/tickers Latest Information for Symbol
  • /v2/public/trading-records Public Trading Records
  • /v2/public/symbols Query Symbol
  • /v2/public/mark-price-kline Query Index Price Kline
  • /v2/public/index-price-kline Query Index Price Kline
  • /v2/public/open-interest Open Interest
  • /v2/public/big-deal Latest Big Deal
  • /v2/public/account-ratio Long-Short Ratio
Account Data Endpoints
  • /futures/private/order/create Place Active Order
  • /futures/private/order/list Get Active Order
  • /futures/private/order/cancel Cancel Active Order
  • /futures/private/order/cancelAll Cancel All Active Orders
  • /futures/private/order Query Active Order (real-time)
  • /futures/private/stop-order/create Place Conditional Order
  • /futures/private/stop-order/list Get Conditional Order
  • /futures/private/stop-order/cancel Cancel Conditional Order
  • /futures/private/stop-order/cancelAll Cancel All Conditional Orders
  • /futures/private/stop-order Query Conditional Order (real-time)
  • /futures/private/position/list My Position
  • /futures/private/position/trading-stop Set Trading-Stop
  • /futures/private/position/leverage/save Set Leverage
  • /v2/private/account/api-key API Key info
Wallet Data Endpoints
  • /v2/private/wallet/balance Get Wallet Balance
Market Data Endpoints
  • /spot/v1/symbols Query Symbol
  • /spot/quote/v1/depth Order Book
  • /spot/quote/v1/depth/merged Merged Order Book
  • /spot/quote/v1/trades Public Trading Records
  • /spot/quote/v1/kline Query Kline
  • /spot/quote/v1/ticker/24hr Latest Information for Symbol
  • /spot/quote/v1/ticker/price Last Traded Price
  • /spot/quote/v1/ticker/book_ticker Best Bid/Ask Price
Account Data Endpoints
  • /spot/v1/order
    • Place Active Order
    • Get Active Order
    • Cancel Active Order
    • Fast Cancel Active Order
  • /spot/v1/order/fast Fast Cancel Active Order
  • /spot/order/batch-cancel Batch Cancel Active Order
  • /spot/order/batch-fast-cancel Batch Fast Cancel Active Order
  • /spot/order/batch-cancel-by-ids Batch Cancel Active Order By IDs
  • /spot/v1/open-orders Open Orders
Wallet Data Endpoints
  • /spot/v1/account Get Wallet Balance

WebSocket API

Public Topics V5

Private Topics V5

Public Topics
  • trade
Public Topics V2
  • trade
Private Topics
  • outboundAccountInfo

Integration Tests

There are tests so that we can get to know the changes of bybit api response.

See below

Contributing

I would like to cover Bybit API and contributions are always welcome. The calling pattern is established, so adding new methods is relatively straightforward. See some PRs like #44.

To submit issues, PRs, and every other help is welcome.

bybit's People

Contributors

0cv avatar back1ng avatar boyi avatar cksidharthan avatar davidphay avatar decanus avatar e-n-0 avatar hirokisan avatar iskorotkov avatar jiamingke avatar josephyim224 avatar kazz187 avatar kbnchk avatar lyro41 avatar mmavka avatar oleksandrdemidov avatar pespantelis avatar quantoor avatar rtunazzz avatar sagleft avatar thasianx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

bybit's Issues

How to make cross margin leverage order ?

Hello, guys.

How can I "simulate" Cross Margin order with levarage?

For example, using UI I got a block with levarage and order together:
image

So, as I understand, I need to borrow money first with Lavarage token and then place order with some parameters?
Thanks

failing tests

some of the tests are failing in the code
maybe checking the return code and return message will suffice and will make the tests more robust?
also need to specify how much usdt should be present in the account before running the test

Testnet

Any reason to make this a constant? https://github.com/hirokisan/bybit/blob/main/client.go#L21

It would be good that it's configurable a way or another with the testnet (https://api-testnet.bybit.com). Also the main net has at least 2 endpoint:

  • https://api.bybit.com
  • https://api.bytick.com

Maybe it's fine that it defaults to the main net. But it shall be possible to overwrite the endpoint

Concurrent write to websocket connection

Hi,

I'm trying to close a websocket service, but I get a panic. I've also tried with mutex, but it didn't help. I've few goroutines connecting to websockets and I'm using wsService.Close() to close a connection.

Could you please check your code? How to properly close a connection?

	wsClient := bybit.NewWebsocketClient().WithAuth(config.Key, config.Secret)
	wsService, err := wsClient.V5().Private()
        err = wsService.Subscribe()
		if err != nil {
			return
		}
...
      err = wsService.Start(context.Background(), errHandler)
      if err != nil {
	      return
      }
panic: concurrent write to websocket connection

goroutine 70 [running]:
github.com/gorilla/websocket.(*messageWriter).flushFrame(0xc0004ae330, 0x1, {0x0?, 0x0?, 0x0?})
	/path/vendor/github.com/gorilla/websocket/conn.go:617 +0x50b
github.com/gorilla/websocket.(*messageWriter).Close(0xc0002870b0?)
	/path/vendor/github.com/gorilla/websocket/conn.go:731 +0x45
github.com/gorilla/websocket.(*Conn).beginMessage(0xc0003022c0, 0xc0002870b0, 0x8)
	/path/vendor/github.com/gorilla/websocket/conn.go:480 +0x42
github.com/gorilla/websocket.(*Conn).NextWriter(0xc0003022c0, 0x8)
	/path/vendor/github.com/gorilla/websocket/conn.go:520 +0x45
github.com/gorilla/websocket.(*Conn).WriteMessage(0x540eb0?, 0xc000072280?, {0xc00026aeb8, 0x2, 0x2})
	/path/vendor/github.com/gorilla/websocket/conn.go:773 +0x152
github.com/hirokisan/bybit/v2.(*V5WebsocketPrivateService).Close(0xc000286ed0)
	/path/vendor/github.com/hirokisan/bybit/v2/v5_ws_private.go:234 +0x59
github.com/hirokisan/bybit/v2.(*V5WebsocketPrivateService).Start(0xc000286ed0, {0x810e48, 0xc00001a730}, 0xc0004ce060)
	/path/vendor/github.com/hirokisan/bybit/v2/v5_ws_private.go:155 +0x377

Thanks

Signing seems to be broken?

I only tested on Testnet

All of the integrationtest/future-usdt-perpetual tests are failing for me with:

10001, empty value: apiTimestamp[] apiKey[] apiSignature[]: openapi sign params error!

I tried regenerating API keys (from https://testnet.bybit.com/en-US/) with the following permissions but I got the same result.
Screenshot 2022-11-14 at 8 16 18 PM

Custom http client

Hello,
would be nice to have option for more customization.
Providing custom http client with custom transport will give option to use proxy.
Also when API limit reached custom client will prevent from making requests.

Sadly changing http client globally not an option as we do not make requests to other exchanges as well.

Warning: int vs int64

There are quite a few places in the app where int is used which is a placeholder for int32 on 32 bits machine and for int64 on 64 bits machine. While 32 bits machine are barely used anymore, thus int defaults to int64, if it were used (or compiled to, like mistakenly in my case, good catch hah!), this will fail to parse a java timestamp, both in the signature such as here or here, or will also fail to parse the response, such as here.

Typically the response error is
json: cannot unmarshal number 1,678,091,666,059 into Go struct field CommonV5Response.time of type int. Indeed because a int32 is maxed out at 2,147,483,647

Probably a low priority issue, but I think int64 shall be used to force 32bits machine to really use 64 bits.

API V5

Hey there,

Are there any plans to support V5?

https://bybit-exchange.github.io/docs/v5/upgrade-guide

Would love to contribute, just wanted to ask if there were any expectations, preferred way of doing things, e.g.

  • 1 Interface for V5?
  • 1 Interface for each segment of V5 (market, order, position etc.)?

panic: repeated read on failed websocket connection

Hi. Thanks for the library

Code

package main

import (
	"context"
	"fmt"
	"github.com/hirokisan/bybit/v2"
	"time"
)

func main() {
	client := bybit.NewClient()
	res, err := client.Future().USDTPerpetual().Symbols()

	wsClient := bybit.NewWebsocketClient()
	svcRoot := wsClient.V5()

	go func() {
		for _, result := range res.Result {
			svc, err := svcRoot.Public(bybit.CategoryV5Linear)
			if err != nil {
				fmt.Println(err)
			}
			_, err = svc.SubscribeKline(bybit.V5WebsocketPublicKlineParamKey{
				Interval: bybit.Interval1,
				Symbol:   bybit.SymbolV5(result.Name),
			}, func(response bybit.V5WebsocketPublicKlineResponse) error {
				fmt.Println(response)
				return nil
			})
			go WS(svc)
		}

	}()

	for {
		time.Sleep(time.Second)
	}
}

func WS(svc bybit.V5WebsocketPublicServiceI) {
	svc.Start(context.Background(), func(isWebsocketClosed bool, err error) {
		fmt.Println(svc, isWebsocketClosed, err)
		WS(svc)
	})
}

I have error:

false read tcp 192.168.1.2:32343->52.84.106.124:443: wsarecv: An existing connection was forcibly closed by the remote host.
false read tcp 192.168.1.2:32343->52.84.106.124:443: wsarecv: An existing connection was forcibly closed by the remote host.
panic: repeated read on failed websocket connection

goroutine 4031 [running]:
github.com/gorilla/websocket.(*Conn).NextReader(0xc001cfa2c0)
        C:/Users/mmavka/go/pkg/mod/github.com/gorilla/[email protected]/conn.go:1030 +0x2a8
github.com/gorilla/websocket.(*Conn).ReadMessage(0x0?)
        C:/Users/mmavka/go/pkg/mod/github.com/gorilla/[email protected]/conn.go:1093 +0x19
github.com/hirokisan/bybit/v2.(*V5WebsocketPublicService).Run(0xc001cc8900)
        C:/Users/mmavka/go/pkg/mod/github.com/hirokisan/bybit/[email protected]/v5_ws_public.go:193 +0x3a
github.com/hirokisan/bybit/v2.(*V5WebsocketPublicService).Start.func1()
        C:/Users/mmavka/go/pkg/mod/github.com/hirokisan/bybit/[email protected]/v5_ws_public.go:152 +0x15d
created by github.com/hirokisan/bybit/v2.(*V5WebsocketPublicService).Start
        C:/Users/mmavka/go/pkg/mod/github.com/hirokisan/bybit/[email protected]/v5_ws_public.go:141 +0xec

Process finished with the exit code 2

Timestamp errors

Hi,

The exchange sometimes returns errors:

Error 10002, invalid request, please check your server timestamp or recv_window param. req_timestamp[1693378842140],server_timestamp[1693378847528],recv_window[5000]

How to fix this?

Thanks

USDTPerp ListLinearPositions doesn't return errors properly

Problem

When calling the ListLinearPositions() method, Unmarshal errors are encountered when the API call does not succeed.

Root Cause

The Bybit API returns an empty result object {} in their response object when an error occurs. For instance, when an invalid API key is used:

{"ret_code":10005,"ret_msg":"Permission denied, please check your API key permissions.","result":{},"ext_code":"","ext_info":"","time_now":"1674306441.372007","rate_limit_status":0,"rate_limit":0,"rate_limit_reset_ms":0}

This value cannot be properly Unmarshalled into an array-like struct, resulting in an error such as:

json: cannot unmarshal object into Go struct field ListLinearPositionsResponse.result of type []bybit.ListLinearPositionsResult

[bug] CancelOrder cannot find OrderLinkID

Hello, I think there is an issue on CancelOrder function with OrderLinkID, when I try to cancel an order I have an error 110001, Order does not exist:

This is the code to reproduce the bug:

package main

import (
	"github.com/hirokisan/bybit/v2"
	log "github.com/sirupsen/logrus"
)

func main() {
	client := bybit.NewClient().WithBaseURL("https://api-testnet.bybit.com").WithAuth("xxx", "xxx")

	symbol := bybit.SymbolV5("BTCUSDT")
	orderlinkid := "test_003"

       // create the order
	client.V5().Order().CreateOrder(bybit.V5CreateOrderParam{
		Category:    bybit.CategoryV5Linear,
		Symbol:      symbol,
		Side:        bybit.Side("Buy"),
		OrderType:   bybit.OrderTypeMarket,
		Qty:         "0.01",
		OrderLinkID: &orderlinkid,
	})

        // ensure the order has been created
	order, err := client.V5().Order().GetOpenOrders(bybit.V5GetOpenOrdersParam{
		Category:    bybit.CategoryV5Linear,
		Symbol:      &symbol,
		OrderLinkID: &orderlinkid,
	})

	if err != nil {
		log.Error(err)
	} else {
		log.Infof("Symbol: %s", order.Result.List[0].Symbol)
		log.Infof("OrderLinkID: %s", order.Result.List[0].OrderLinkID)
	}


       // Remove the order
	_, err = client.V5().Order().CancelOrder(bybit.V5CancelOrderParam{
		Category:    bybit.CategoryV5Linear,
		Symbol:      symbol,
		OrderLinkID: &orderlinkid,
	})

	if err != nil {
		log.Error(err)
	}
}

An this is the output:

INFO[0000] Symbol: BTCUSDT                              
INFO[0000] OrderLinkID: test_003                        
ERRO[0001] 110001, Order does not exist

Did I miss something wrong ?

USDT Derivatives balance empty

Hello,

Thanks for this module! I was trying to get the balance for my USDT derivatives wallet on bybit, but it seems I always get an empty response. Can you point me in the right direction?

package main

import (
	"fmt"

	"github.com/hirokisan/bybit"
)

func main() {

	client := bybit.NewClient().WithAuth("xxxxx", "xxxxxxx")
	res, err := client.Wallet().Balance(bybit.CoinUSDT)
	if err != nil {
		fmt.Println(err)
	}
	if client.HasAuth() {
		fmt.Println(res.Result)
	}
}

thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.