Security News
The Risks of Misguided Research in Supply Chain Security
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
github.com/deepln-io/longbridge-goapi
Long Bridge is a promising broker emerging in the stock market with first rate trading app. Recently (May 10, 2022) they released the OpenAPI for quants https://longbridgeapp.com/en/topics/2543341?channel=t2543341&invite-code=0VMCD7.
This is a go implementation of full long bridge broker APIs based on the document in https://open.longbridgeapp.com/en/docs.
For API in other languages, please refer to longbridge's official github site at https://github.com/longbridgeapp.
go get github.com/deepln-io/longbridge-goapi
The package provides two sets of APIs through TradeClient and QuoteClient for trading and quote respectively.
The library automatically manages the connection to long bridge servers and will reconnect if disconnected. This is useful for real production systems when a trading bot is running continuously overnight.
To use the trade notification, set order notification call back through TradeClient.OnOrderChange(order *longbridge.Order).
Note to run the examples, please make sure that your long bridge account is ready with access token, app key and secret available. Set them in env variable before running.
export LB_ACCESS_TOKEN="<access token from your account's developer center>"
export LB_APP_KEY="<your app key>"
export LB_APP_SECRET="<your app secret>"
Get the stock static information. The code connects to long bridge, gets down the static security information, and prints them out.
package main
import (
"log"
"os"
"github.com/deepln-io/longbridge-goapi"
)
func main() {
c, err := longbridge.NewQuoteClient(&longbridge.Config{
AccessToken: os.Getenv("LB_ACCESS_TOKEN"),
AppKey: os.Getenv("LB_APP_KEY"),
AppSecret: os.Getenv("LB_APP_SECRET"),
QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020", // Optionally choose TCP connection here
})
if err != nil {
log.Fatalf("Error creating longbridge client: %v", err)
}
defer c.Close()
ss, err := c.GetStaticInfo([]string{"700.HK", "AAPL.US"})
if err != nil {
log.Fatalf("Error getting static info: %v", err)
}
for _, s := range ss {
log.Printf("%#v\n", s)
}
}
Get real time price Make sure you have real time quote access permission from Long Bridge.
package main
import (
"log"
"os"
"github.com/deepln-io/longbridge-goapi"
)
func main() {
c, err := longbridge.NewQuoteClient(&longbridge.Config{
AccessToken: os.Getenv("LB_ACCESS_TOKEN"),
AppKey: os.Getenv("LB_APP_KEY"),
AppSecret: os.Getenv("LB_APP_SECRET"),
})
if err != nil {
log.Fatalf("Error creating longbridge client: %v", err)
}
defer c.Close()
qs, err := c.GetRealtimeQuote([]string{"5.HK", "MSFT.US"})
if err != nil {
log.Fatalf("Error getting real time quote: %v", err)
}
for _, q := range qs {
log.Printf("%#v\n", q)
}
}
Get account positions
package main
import (
"log"
"os"
"github.com/deepln-io/longbridge-goapi"
)
func main() {
c, err := longbridge.NewTradeClient(&longbridge.Config{
AccessToken: os.Getenv("LB_ACCESS_TOKEN"),
AppKey: os.Getenv("LB_APP_KEY"),
AppSecret: os.Getenv("LB_APP_SECRET"),
})
if err != nil {
log.Fatalf("Error creating longbridge client: %v", err)
}
defer c.Close()
positions, err := c.GetStockPositions()
if err != nil {
log.Fatalf("Error getting stock positions: %v", err)
}
for _, position := range positions {
log.Printf("%+v", position)
}
}
Place an order
package main
import (
"log"
"os"
"time"
"github.com/deepln-io/longbridge-goapi"
)
func main() {
c, err := longbridge.NewTradeClient(&longbridge.Config{
AccessToken: os.Getenv("LB_ACCESS_TOKEN"),
AppKey: os.Getenv("LB_APP_KEY"),
AppSecret: os.Getenv("LB_APP_SECRET"),
})
if err != nil {
log.Fatalf("Error creating longbridge client: %v", err)
}
defer c.Close()
orderID, err := c.PlaceOrder(&longbridge.PlaceOrderReq{
Symbol: "AMD.US",
OrderType: longbridge.LimitOrder,
Price: 180,
Quantity: 1,
ExpireDate: time.Now().AddDate(0, 1, 0),
Side: longbridge.Sell,
OutsideRTH: longbridge.AnyTime,
TimeInForce: longbridge.GoodTilCancel,
Remark: "钓鱼单",
})
if err != nil {
log.Fatalf("Error placing order: %v", err)
}
Place, modify and cancel order
package main
import (
"log"
"os"
"time"
"github.com/deepln-io/longbridge-goapi"
)
func main() {
c, err := longbridge.NewTradeClient(&longbridge.Config{
AccessToken: os.Getenv("LB_ACCESS_TOKEN"),
AppKey: os.Getenv("LB_APP_KEY"),
AppSecret: os.Getenv("LB_APP_SECRET"),
})
if err != nil {
log.Fatalf("Error creating longbridge client: %v", err)
}
defer c.Close()
orderID, err := c.PlaceOrder(&longbridge.PlaceOrderReq{
Symbol: "AMD.US",
OrderType: longbridge.LimitOrder,
Price: 180,
Quantity: 1,
ExpireDate: time.Now().AddDate(0, 1, 0),
Side: longbridge.Sell,
OutsideRTH: longbridge.AnyTime,
TimeInForce: longbridge.GoodTilCancel,
Remark: "钓鱼单",
})
if err != nil {
log.Fatalf("Error placing order: %v", err)
}
time.Sleep(time.Second)
if err := c.ModifyOrder(&longbridge.ModifyOrderReq{
OrderID: orderID,
Quantity: 1,
Price: 200,
TriggerPrice: 200,
}); err != nil {
log.Fatalf("Error modifying submitted order (id: %v): %v", orderID, err)
}
log.Printf("Order modified successfully, ID: %v", orderID)
time.Sleep(time.Second)
if err := c.CancelOrder(orderID); err != nil {
log.Fatalf("Error cancelling submitted order (id: %v): %v", orderID, err)
}
log.Printf("Order cancelled successfully, ID: %v", orderID)
}
Pull real time tick data
package main
import (
"log"
"os"
"github.com/deepln-io/longbridge-goapi"
)
func main() {
c, err := longbridge.NewQuoteClient(&longbridge.Config{
AccessToken: os.Getenv("LB_ACCESS_TOKEN"),
AppKey: os.Getenv("LB_APP_KEY"),
AppSecret: os.Getenv("LB_APP_SECRET"),
})
if err != nil {
log.Fatalf("Error creating longbridge client: %v", err)
}
defer c.Close()
ts, err := c.GetTickers("AAPL.US", 10)
if err != nil {
log.Fatalf("Error getting tickers for: %v", err)
}
for _, t := range ts {
log.Printf("%#v", t)
}
}
Subscribe level 2 tick data with callback
package main
import (
"log"
"os"
"time"
"github.com/deepln-io/longbridge-goapi"
)
func main() {
c, err := longbridge.NewQuoteClient(&longbridge.Config{
AccessToken: os.Getenv("LB_ACCESS_TOKEN"),
AppKey: os.Getenv("LB_APP_KEY"),
AppSecret: os.Getenv("LB_APP_SECRET"),
})
if err != nil {
log.Fatalf("Error creating longbridge client: %v", err)
}
defer c.Close()
c.OnPushTickers = func(t *longbridge.PushTickers) {
log.Printf("Got tickers for %s, seq=%d", t.Symbol, t.Sequence)
for _, ticker := range t.Tickers {
log.Printf("Ticker: %#v", ticker)
}
}
ss, err := c.SubscribePush([]string{"AAPL.US"},
[]longbridge.SubscriptionType{longbridge.SubscriptionTicker}, true)
if err != nil {
log.Fatalf("Error subscribe quote push: %v", err)
}
for _, s := range ss {
log.Printf("%#v", s)
}
time.Sleep(30 * time.Second)
if err := c.UnsubscribePush(nil,
[]longbridge.SubscriptionType{longbridge.SubscriptionTicker}, true); err != nil {
log.Fatalf("Error unsubscribing all symbols' quote push: %v", err)
}
}
Thanks the long bridge development team for patiently replying a lot of technical questions to clarify the API details during our development.
When longbridge protobuf files are updated, run the script gen-pb.sh in internal dir and push the changes.
We are always happy to welcome new contributors! If you have any questions, please feel free to reach out by opening an issue or leaving a comment.
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.