longbridge

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 19, 2022 License: MIT Imports: 30 Imported by: 0

README

Long Bridge Broker Golang API

PkgGoDev

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.

Features

  • Support full long bridge APIs for trading, accessing to account portfolio and subscribing real time market data.
  • Strong typed APIs.
  • Maintain auto reconnection of long connection for trading and quote subscriptions to fit for full automatic production environment.
  • Support both secured web socket and TCP connection.
  • Pure golang implementation.

Installation

go get github.com/deepln-io/longbridge-goapi

How to use it

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>"

Examples

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)
	}
}

Acknowledge

Thanks the long bridge development team for patiently replying a lot of technical questions to clarify the API details during our development.

License

MIT License

Development

When longbridge protobuf files are updated, run the script gen-pb.sh in internal dir and push the changes.

Contributing

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.

Documentation

Overview

Package longbridge implements the long bridge trading and quote API. It provides two clients, TradeClient and QuoteClient, to access trading service and quote service respectively. The API implementation strictly follows the document at https://open.longbridgeapp.com/docs. For each exported API, we have related short test examples. To run the examples, set the environment variables for LB_APP_KEY, LB_APP_SECRET, and LB_ACCESS_TOKEN obtained from long bridge developer center page.

For debugging, set -logtostderr and -v=<log level> to print out the internal protocol flow to console. In the implementation, glog is used to print different level of logging information. The log level rule is:

Without V(n), show the log that are essential to be known by caller.
V(2) for normal verbose notification for error cases.
V(3) for deubgging information and consists detailed variable information.
V(4) for high frequency repeated debugging information.

Index

Examples

Constants

View Source
const (
	LimitOrder           OrderType = "LO"
	EnhancedLimitOrder   OrderType = "ELO"
	MarketOrder          OrderType = "MO"
	AtAuctionMarketOrder OrderType = "AO"
	AtAuctionLimitOrder  OrderType = "ALO"
	OddLotsOrder         OrderType = "ODD"     // 碎股單掛單
	LimitIfTouched       OrderType = "LIT"     // 觸價限價單
	MarketIfTouched      OrderType = "MIT"     // 觸價市價單
	TSLPAMT              OrderType = "TSLPAMT" // Trailing Limit If Touched (Trailing Amount) 跟蹤止損限價單 (跟蹤金额)
	TSLPPCT              OrderType = "TSLPPCT" // Trailing Limit If Touched (Trailing Percent) 跟蹤止損限價單 (跟蹤漲跌幅)
	TSMAMT               OrderType = "TSMAMT"  // Trailing Market If Touched (Trailing Amount) 跟蹤止損市價單 (跟蹤金额)
	TSMPCT               OrderType = "TSMPCT"  // Trailing Market If Touched (Trailing Percent) 跟蹤止損市價單 (跟蹤漲跌幅)

	Buy  TrdSide = "Buy"
	Sell TrdSide = "Sell"

	DayOrder      TimeInForce = "Day" // 當日有效
	GoodTilCancel TimeInForce = "GTC" // 撤單前有效
	GoodTilDate   TimeInForce = "GTD" // 到期前有效

	RTHOnly OutsideRTH = "RTH_ONLY" // Regular trading hour only
	AnyTime OutsideRTH = "ANY_TIME"

	NotReported          OrderStatus = "NotReported"          // 待提交
	ReplacedNotReported  OrderStatus = "ReplacedNotReported"  // 待提交 (改單成功)
	ProtectedNotReported OrderStatus = "ProtectedNotReported" // 待提交 (保價訂單)
	VarietiesNotReported OrderStatus = "VarietiesNotReported" // 待提交 (條件單)
	FilledStatus         OrderStatus = "FilledStatus"         // 已成交
	WaitToNew            OrderStatus = "WaitToNew"            // 已提待報
	NewStatus            OrderStatus = "NewStatus"            // 已委托
	WaitToReplace        OrderStatus = "WaitToReplace"        // 修改待報
	PendingReplaceStatus OrderStatus = "PendingReplaceStatus" // 待修改
	ReplacedStatus       OrderStatus = "ReplacedStatus"       // 已修改
	PartialFilledStatus  OrderStatus = "PartialFilledStatus"  // 部分成交
	WaitToCancel         OrderStatus = "WaitToCancel"         // 撤銷待報
	PendingCancelStatus  OrderStatus = "PendingCancelStatus"  // 待撤回
	RejectedStatus       OrderStatus = "RejectedStatus"       // 已拒絕
	CanceledStatus       OrderStatus = "CanceledStatus"       // 已撤單
	ExpiredStatus        OrderStatus = "ExpiredStatus"        // 已過期
	PartialWithdrawal    OrderStatus = "PartialWithdrawal"    // 部分撤單

	NormalOrder OrderTag = "Normal" // Normal order
	GTCOrder    OrderTag = "GTC"    // Long term order
	GreyOrder   OrderTag = "Grey"   // Grey order 暗盤單

	NotUsed  TriggerStatus = "NOT_USED" // 未激活
	Deactive TriggerStatus = "DEACTIVE"
	Active   TriggerStatus = "ACTIVE"
	Released TriggerStatus = "RELEASED" // 已觸發
)
View Source
const (
	TradeStatusNormal             = TradeStatus(quote.TradeStatus_NORMAL)
	TradeStatusHalted             = TradeStatus(quote.TradeStatus_HALTED)
	TradeStatusDelisted           = TradeStatus(quote.TradeStatus_DELISTED)
	TradeStatusFuse               = TradeStatus(quote.TradeStatus_FUSE)
	TradeStatusPrepareList        = TradeStatus(quote.TradeStatus_PREPARE_LIST)
	TradeStatusCodeMoved          = TradeStatus(quote.TradeStatus_CODE_MOVED)
	TradeStatusToBeOpened         = TradeStatus(quote.TradeStatus_TO_BE_OPENED)
	TradeStatusSlitStockHalts     = TradeStatus(quote.TradeStatus_SPLIT_STOCK_HALTS)
	TradeStatusExpired            = TradeStatus(quote.TradeStatus_EXPIRED)
	TradeStatusWarrantPrepareList = TradeStatus(quote.TradeStatus_WARRANT_PREPARE_LIST)
	TradeStatusSuspendTrade       = TradeStatus(quote.TradeStatus_SUSPEND_TRADE)
)
View Source
const (
	DirNeutral = TradeDir(0)
	DirDown    = TradeDir(1)
	DirUp      = TradeDir(2)
)
View Source
const (
	SubscriptionRealtimeQuote = SubscriptionType(quote.SubType_QUOTE)
	SubscriptionOrderBook     = SubscriptionType(quote.SubType_DEPTH)
	SubscriptionBrokerQueue   = SubscriptionType(quote.SubType_BROKERS)
	SubscriptionTicker        = SubscriptionType(quote.SubType_TRADE)
)

Variables

View Source
var (

	// OrderTypes includes all order types in predefined order.
	OrderTypes = []OrderType{
		MarketOrder,
		LimitOrder,
		EnhancedLimitOrder,
		AtAuctionMarketOrder,
		AtAuctionLimitOrder,
		OddLotsOrder,
		LimitIfTouched,
		MarketIfTouched,
		TSLPAMT,
		TSLPPCT,
		TSMAMT,
		TSMPCT,
	}
)

Functions

This section is empty.

Types

type AccessTokenInfo

type AccessTokenInfo struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    struct {
		Token       string    `json:"token"`
		ExpiredAt   time.Time `json:"expired_at"`
		IssuedAt    time.Time `json:"issued_at"`
		AccountInfo struct {
			MemberID       string `json:"member_id"`
			Aaid           string `json:"aaid"`
			AccountChannel string `json:"account_channel"`
		} `json:"account_info"`
	} `json:"data"`
}

type AdjustType

type AdjustType int32

type AssetType

type AssetType int
const (
	CashAsset AssetType = iota + 1
	StockAsset
	FundAsset
)

type Balance

type Balance struct {
	TotalCash           float64
	MaxFinanceAmount    float64
	RemainFinanceAmount float64
	RiskLevel           RiskLevel
	MarginCall          float64
	NetAssets           float64
	InitMargin          float64
	MaintenanceMargin   float64
	Currency            string
	Cashes              []*Cash
}

type Broker

type Broker struct {
	Position int32
	IDs      []int32
}

type BrokerInfo

type BrokerInfo struct {
	IDs         []int32
	NameEnglish string
	NameChinese string
	NameHK      string
}

type BrokerQueue

type BrokerQueue struct {
	Symbol Symbol
	Bid    []*Broker
	Ask    []*Broker
}

type CapDistribution

type CapDistribution struct {
	Large  float64
	Medium float64
	Small  float64
}

type CapFlowDistribution

type CapFlowDistribution struct {
	Symbol    Symbol
	Timestamp int64
	InFlow    CapDistribution
	OutFlow   CapDistribution
}

type Cash

type Cash struct {
	Withdraw  float64
	Available float64
	Frozen    float64
	Settling  float64
	Currency  string
}

type Cashflow

type Cashflow struct {
	TransactionFlowName string
	Direction           CashflowDirection
	BusinessType        AssetType
	Balance             float64
	Currency            string
	BusinessTimestamp   int64
	Symbol              Symbol // Optional
	Description         string // Optional
}

type CashflowDirection

type CashflowDirection int
const (
	Outflow CashflowDirection = iota + 1
	Inflow
)

type CashflowReq

type CashflowReq struct {
	StartTimestamp int64
	EndTimestamp   int64
	BusinessType   AssetType
	Symbol         Symbol
	// Page is start page (>= 1), default is 1.
	Page uint64
	// Size is page size (1 ~ 10000), default is 50.
	Size uint64
	// IsAll indicates if get all cash flows. Default is get cash flows in current page.
	IsAll bool
}

CashflowReq is the request to get cash flows. Only field StartTimestamp and EndTimestamp are required.

type Config

type Config struct {
	AccessToken       string // Required
	AppKey            string // Required
	AppSecret         string // Required
	BaseURL           string // Optional, if not set, use default base URL https://openapi.longbridgeapp.com
	TradeEndpoint     string // Optional, if not set, use wss://openapi-trade.longbridgeapp.com
	QuoteEndpoint     string // Optional, if not set, use wss://openapi-quote.longbridgeapp.com
	ReconnectInterval int    // Optional, if not set, use default 3 seconds for reconnecting to the above endpoints
}

Config contains the network address and the necessary credential information for accessing long bridge service.

type FinanceIndex

type FinanceIndex = quote.CalcIndex
const (
	IndexUnknown                 FinanceIndex = quote.CalcIndex_CALCINDEX_UNKNOWN
	IndexLastDone                FinanceIndex = quote.CalcIndex_CALCINDEX_LAST_DONE
	IndexChangeVal               FinanceIndex = quote.CalcIndex_CALCINDEX_CHANGE_VAL
	IndexChangeRate              FinanceIndex = quote.CalcIndex_CALCINDEX_CHANGE_RATE
	IndexVolume                  FinanceIndex = quote.CalcIndex_CALCINDEX_VOLUME
	IndexTurnover                FinanceIndex = quote.CalcIndex_CALCINDEX_TURNOVER
	IndexYtdChange_RATE          FinanceIndex = quote.CalcIndex_CALCINDEX_YTD_CHANGE_RATE
	IndexTurnoverRate            FinanceIndex = quote.CalcIndex_CALCINDEX_TURNOVER_RATE
	IndexTotalMarket_VALUE       FinanceIndex = quote.CalcIndex_CALCINDEX_TOTAL_MARKET_VALUE
	IndexCapitalFlow             FinanceIndex = quote.CalcIndex_CALCINDEX_CAPITAL_FLOW
	IndexAmplitude               FinanceIndex = quote.CalcIndex_CALCINDEX_AMPLITUDE
	IndexVolumeRatio             FinanceIndex = quote.CalcIndex_CALCINDEX_VOLUME_RATIO
	IndexPeTtm_RATIO             FinanceIndex = quote.CalcIndex_CALCINDEX_PE_TTM_RATIO
	IndexPbRatio                 FinanceIndex = quote.CalcIndex_CALCINDEX_PB_RATIO
	IndexDividendRatio_TTM       FinanceIndex = quote.CalcIndex_CALCINDEX_DIVIDEND_RATIO_TTM
	IndexFiveDay_CHANGE_RATE     FinanceIndex = quote.CalcIndex_CALCINDEX_FIVE_DAY_CHANGE_RATE
	IndexTenDay_CHANGE_RATE      FinanceIndex = quote.CalcIndex_CALCINDEX_TEN_DAY_CHANGE_RATE
	IndexHalfYear_CHANGE_RATE    FinanceIndex = quote.CalcIndex_CALCINDEX_HALF_YEAR_CHANGE_RATE
	IndexFiveMinutes_CHANGE_RATE FinanceIndex = quote.CalcIndex_CALCINDEX_FIVE_MINUTES_CHANGE_RATE
	IndexExpiryDate              FinanceIndex = quote.CalcIndex_CALCINDEX_EXPIRY_DATE
	IndexStrikePrice             FinanceIndex = quote.CalcIndex_CALCINDEX_STRIKE_PRICE
	IndexUpperStrike_PRICE       FinanceIndex = quote.CalcIndex_CALCINDEX_UPPER_STRIKE_PRICE
	IndexLowerStrike_PRICE       FinanceIndex = quote.CalcIndex_CALCINDEX_LOWER_STRIKE_PRICE
	IndexOutstandingQty          FinanceIndex = quote.CalcIndex_CALCINDEX_OUTSTANDING_QTY
	IndexOutstandingRatio        FinanceIndex = quote.CalcIndex_CALCINDEX_OUTSTANDING_RATIO
	IndexPremium                 FinanceIndex = quote.CalcIndex_CALCINDEX_PREMIUM
	IndexItmOtm                  FinanceIndex = quote.CalcIndex_CALCINDEX_ITM_OTM
	IndexImpliedVolatility       FinanceIndex = quote.CalcIndex_CALCINDEX_IMPLIED_VOLATILITY
	IndexWarrantDelta            FinanceIndex = quote.CalcIndex_CALCINDEX_WARRANT_DELTA
	IndexCallPrice               FinanceIndex = quote.CalcIndex_CALCINDEX_CALL_PRICE
	IndexToCall_PRICE            FinanceIndex = quote.CalcIndex_CALCINDEX_TO_CALL_PRICE
	IndexEffectiveLeverage       FinanceIndex = quote.CalcIndex_CALCINDEX_EFFECTIVE_LEVERAGE
	IndexLeverageRatio           FinanceIndex = quote.CalcIndex_CALCINDEX_LEVERAGE_RATIO
	IndexConversionRatio         FinanceIndex = quote.CalcIndex_CALCINDEX_CONVERSION_RATIO
	IndexBalancePoint            FinanceIndex = quote.CalcIndex_CALCINDEX_BALANCE_POINT
	IndexOpenInterest            FinanceIndex = quote.CalcIndex_CALCINDEX_OPEN_INTEREST
	IndexDelta                   FinanceIndex = quote.CalcIndex_CALCINDEX_DELTA
	IndexGamma                   FinanceIndex = quote.CalcIndex_CALCINDEX_GAMMA
	IndexTheta                   FinanceIndex = quote.CalcIndex_CALCINDEX_THETA
	IndexVega                    FinanceIndex = quote.CalcIndex_CALCINDEX_VEGA
	IndexRho                     FinanceIndex = quote.CalcIndex_CALCINDEX_RHO
)

type FundPosition

type FundPosition struct {
	Symbol                 Symbol
	SymbolName             string
	Currency               string
	HoldingUnits           float64
	CurrentNetAssetValue   float64
	CostNetAssetValue      float64
	NetAssetValueTimestamp int64
	AccountChannel         string
}

type GetHistoryOrderFillsReq

type GetHistoryOrderFillsReq struct {
	Symbol         Symbol
	StartTimestamp int64
	EndTimestamp   int64
}

GetHistoryOrderFillsReq is a request to get history order fills (executions).

type GetHistoryOrdersReq

type GetHistoryOrdersReq struct {
	Symbol         Symbol
	Status         []OrderStatus
	Side           TrdSide
	Market         Market
	StartTimestamp int64
	EndTimestamp   int64
}

GetHistoryOrdersReq is the request to get history orders. All fields are optional.

type GetTodayOrderFillsReq

type GetTodayOrderFillsReq struct {
	Symbol  Symbol
	OrderID uint64
}

GetTodayOrderFillsReq is a request to get today's order fills (executions). All fields are optional filters.

type GetTodyOrdersReq

type GetTodyOrdersReq struct {
	Symbol  Symbol
	Status  []OrderStatus
	Side    TrdSide
	Market  Market
	OrderID uint64
}

GetTodyOrdersReq is the request to get today orders. All fields are optional.

type IntradayCapFlow

type IntradayCapFlow struct {
	Flow      float64
	Timestamp int64
}

type IntradayLine

type IntradayLine struct {
	Price     float64
	Timestamp int64
	Volume    int64
	Turnover  float64
	AvgPrice  float64
}

type Issuer

type Issuer struct {
	ID     int32
	NameCn string
	NameEn string
	NameHk string
}

type KLine

type KLine struct {
	Open      float64
	High      float64
	Low       float64
	Close     float64
	Volume    int64
	Turnover  float64
	Timestamp int64
}

type KLineType

type KLineType int32

type Language

type Language int32
const (
	SimplifiedChinese  Language = 0
	English            Language = 1
	TraditionalChinese Language = 2
)

type MarginRatio

type MarginRatio struct {
	InitRatio        float64
	MaintenanceRatio float64
	ForcedSaleRatio  float64
}

type Market

type Market string
const (
	HK Market = "HK"
	US Market = "US"
)

type MarketSession

type MarketSession struct {
	SessionType TradeSessionType
	BeginTime   int32 // The time is encoded with int as HHMM, e.g., 930 means 9:30am, and it is in the corresponding market timezone.
	EndTime     int32
}

type MarketTradePeriod

type MarketTradePeriod struct {
	Market        Market
	TradeSessions []*MarketSession
}

type ModifyOrderReq

type ModifyOrderReq struct {
	OrderID  string // Required
	Quantity uint64 // Required
	// Price is optional, required for order of type LO/ELO/ALO/ODD/LIT
	Price           float64
	TriggerPrice    float64
	LimitOffset     float64
	TrailingAmount  float64
	TrailingPercent float64
	Remark          string // Max 64 characters
}

ModifyOrderReq is a request to modify order.

type OptionExtend

type OptionExtend struct {
	ImpliedVolatility    float64
	OpenInterest         int64
	ExpiryDate           string // YYMMDD
	StrikePrice          float64
	ContractMultiplier   float64
	ContractType         string
	ContractSize         float64
	Direction            string
	HistoricalVolatility float64
	UnderlyingSymbol     Symbol
}

type Order

type Order struct {
	Currency           string // Required
	ExecutedPrice      float64
	ExecutedQuantity   uint64
	ExpireDate         string // In format of 'YYYY-MM-DD' if provided
	LastDone           string
	LimitOffset        float64
	Msg                string
	OrderID            uint64    // Required
	OrderType          OrderType // Required
	OutsideRTH         OutsideRTH
	Price              float64
	Quantity           uint64      // Required
	Side               TrdSide     // Required
	Status             OrderStatus // Required
	StockName          string      // Required
	SubmittedTimestamp int64       // Required
	Symbol             Symbol      // Required
	Tag                OrderTag    // Required
	TimeInForce        TimeInForce // Required
	TrailingAmount     float64
	TrailingPercent    float64
	TriggerTimestamp   int64
	TriggerPrice       float64
	TriggerStatus      TriggerStatus
	UpdatedTimestamp   int64
}

type OrderBook

type OrderBook struct {
	Position int32
	Price    float64
	Volume   int64
	OrderNum int64
}

type OrderBookList

type OrderBookList struct {
	Symbol Symbol
	Bid    []*OrderBook
	Ask    []*OrderBook
}

type OrderFill

type OrderFill struct {
	OrderID            uint64
	Price              float64
	Quantity           uint64
	Symbol             Symbol
	TradeDoneTimestamp int64
	TradeID            string
}

type OrderStatus

type OrderStatus string

type OrderTag

type OrderTag string

type OrderType

type OrderType string

func (OrderType) String

func (ot OrderType) String() string

type OutsideRTH

type OutsideRTH string // Outside regular trading hours

type PlaceOrderReq

type PlaceOrderReq struct {
	// Stock symbol: Required, use ticker.region format, example: AAPL.US
	Symbol Symbol
	// Order type: Required
	OrderType OrderType
	Price     float64 // For limit order (LO, ELO, ALO)
	// Quantity: Required
	Quantity        uint64
	TriggerPrice    float64
	LimitOffset     float64
	TrailingAmount  float64
	TrailingPercent float64
	// Expire date (in timezone HKT or EDT) for long term order
	ExpireDate time.Time
	// Trade side: Required
	Side       TrdSide
	OutsideRTH OutsideRTH
	// Time in force: Required
	TimeInForce TimeInForce
	Remark      string // Max 64 characters
}

PlaceOrderReq is a request to place order. Fields are optional unless marked as 'Required'.

type PostMarketQuote

type PostMarketQuote struct {
	LastDone  float64
	Timestamp int64
	Volume    int64
	Turnover  float64
	High      float64
	Low       float64
	PrevClose float64
}

type PreMarketQuote

type PreMarketQuote struct {
	LastDone  float64
	Timestamp int64
	Volume    int64
	Turnover  float64
	High      float64
	Low       float64
	PrevClose float64
}

type PushBrokers

type PushBrokers struct {
	Symbol   Symbol
	Sequence int64
	Bid      []*Broker
	Ask      []*Broker
}

type PushOrderBook

type PushOrderBook struct {
	Symbol   Symbol
	Sequence int64
	Bid      []*OrderBook
	Ask      []*OrderBook
}

type PushQuote

type PushQuote struct {
	Symbol          Symbol
	Sequence        int64
	LastDone        float64
	Open            float64
	High            float64
	Low             float64
	Timestamp       int64
	Volume          int64
	Turnover        float64
	TradeStatus     TradeStatus
	TradeSession    TradeSessionType
	CurrentVolume   int64
	CurrentTurnover float64
}

type PushTickers

type PushTickers struct {
	Symbol   Symbol
	Sequence int64
	Tickers  []*Ticker
}

type QotSubscription

type QotSubscription struct {
	Symbol        Symbol
	Subscriptions []SubscriptionType
}

type QuoteClient

type QuoteClient struct {
	// contains filtered or unexported fields
}

func NewQuoteClient

func NewQuoteClient(conf *Config) (*QuoteClient, error)

func (*QuoteClient) Close

func (c *QuoteClient) Close()

func (QuoteClient) GetBrokerInfo

func (c QuoteClient) GetBrokerInfo() ([]*BrokerInfo, error)
Example
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()
bs, err := c.GetBrokerInfo()
if err != nil {
	log.Fatalf("Error getting broker queue for: %v", err)
}
for _, b := range bs {
	log.Printf("%#v", b)
}
Output:

func (QuoteClient) GetBrokerQueue

func (c QuoteClient) GetBrokerQueue(symbol Symbol) (*BrokerQueue, error)
Example
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()
bq, err := c.GetBrokerQueue("5.HK")
if err != nil {
	log.Fatalf("Error getting broker queue for: %v", err)
}
log.Printf("%s\n", bq.Symbol)
for _, bid := range bq.Bid {
	log.Printf("%#v\n", bid)
}
for _, ask := range bq.Ask {
	log.Printf("%#v\n", ask)
}
Output:

func (QuoteClient) GetFinanceIndices

func (c QuoteClient) GetFinanceIndices(symbols []Symbol, indices []FinanceIndex) ([]*SecurityFinanceIndex, error)
Example
c, err := longbridge.NewQuoteClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
fs, err := c.GetFinanceIndices([]longbridge.Symbol{"700.HK", "5.HK"},
	[]longbridge.FinanceIndex{longbridge.IndexLastDone, longbridge.IndexBalancePoint, longbridge.IndexCapitalFlow, longbridge.IndexExpiryDate})
if err != nil {
	log.Fatalf("Error getting intraday capital flow distribution: %v", err)
}
for _, f := range fs {
	log.Printf("%+v", f)
}
Output:

func (QuoteClient) GetIntradayCapFlowDistribution

func (c QuoteClient) GetIntradayCapFlowDistribution(symbol Symbol) (*CapFlowDistribution, error)
Example
c, err := longbridge.NewQuoteClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
cd, err := c.GetIntradayCapFlowDistribution("700.HK")
if err != nil {
	log.Fatalf("Error getting intraday capital flow distribution: %v", err)
}
log.Printf("%+v", cd)
Output:

func (QuoteClient) GetIntradayCapFlows

func (c QuoteClient) GetIntradayCapFlows(symbol Symbol) ([]*IntradayCapFlow, error)
Example
c, err := longbridge.NewQuoteClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
fs, err := c.GetIntradayCapFlows("700.HK")
if err != nil {
	log.Fatalf("Error getting intraday capital flow: %v", err)
}
for _, f := range fs {
	log.Printf("%+v", f)
}
Output:

func (QuoteClient) GetIntradayLines

func (c QuoteClient) GetIntradayLines(symbol Symbol) ([]*IntradayLine, error)
Example
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()
ls, err := c.GetIntradayLines("AAPL.US")
if err != nil {
	log.Fatalf("Error getting tickers for: %v", err)
}
for _, l := range ls {
	log.Printf("%#v", l)
}
Output:

func (QuoteClient) GetKLines

func (c QuoteClient) GetKLines(symbol Symbol, klType KLineType, count int32, adj AdjustType) ([]*KLine, error)
Example
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()
ks, err := c.GetKLines("AAPL.US", longbridge.KLine1M, 10, longbridge.AdjustNone)
if err != nil {
	log.Fatalf("Error getting klines: %v", err)
}
for _, k := range ks {
	log.Printf("%#v", k)
}
Output:

func (QuoteClient) GetMarketTradePeriods

func (c QuoteClient) GetMarketTradePeriods() ([]*MarketTradePeriod, error)
Example
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()
ms, err := c.GetMarketTradePeriods()
if err != nil {
	log.Fatalf("Error getting market periods: %v", err)
}
for _, m := range ms {
	log.Printf("%#v", m.Market)
	for _, s := range m.TradeSessions {
		log.Printf("%#v", s)
	}
}
Output:

func (QuoteClient) GetOptionExpiryDates

func (c QuoteClient) GetOptionExpiryDates(symbol Symbol) ([]string, error)

GetOptionExpiryDates returns the expiry dates for a stock. The dates are encoded as YYMMDD, with timezone related to its corresponding market.

Example
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()
ks, err := c.GetOptionExpiryDates("AAPL.US")
if err != nil {
	log.Fatalf("Error getting option chain expiry dates: %v", err)
}
for _, k := range ks {
	log.Printf("%#v", k)
}
Output:

func (QuoteClient) GetOptionStrikePrices

func (c QuoteClient) GetOptionStrikePrices(symbol Symbol, expiry string) ([]*StrikePriceInfo, error)

GetOptionStrikePrices returns the strike price list for a stock's option chain on given expiry date (in YYYYMMDD format).

Example
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()
ks, err := c.GetOptionStrikePrices("AAPL.US", "20230120")
if err != nil {
	log.Fatalf("Error getting option chain strike price: %v", err)
}
for _, k := range ks {
	log.Printf("%#v", k)
}
Output:

func (QuoteClient) GetOrderBookList

func (c QuoteClient) GetOrderBookList(symbol Symbol) (*OrderBookList, error)
Example
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()
ol, err := c.GetOrderBookList("5.HK")
if err != nil {
	log.Fatalf("Error getting order book for: %v", err)
}
log.Printf("%s\n", ol.Symbol)
for _, bid := range ol.Bid {
	log.Printf("%#v\n", bid)
}
for _, ask := range ol.Ask {
	log.Printf("%#v\n", ask)
}
Output:

func (QuoteClient) GetRealtimeOptionQuote

func (c QuoteClient) GetRealtimeOptionQuote(symbols []Symbol) ([]*RealtimeOptionQuote, error)
Example
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.GetRealtimeOptionQuote([]longbridge.Symbol{"AAPL230317P160000.US"})
if err != nil {
	log.Fatalf("Error getting real time option quote: %v", err)
}
for _, q := range qs {
	log.Printf("%#v\n", q)
}
Output:

func (QuoteClient) GetRealtimeQuote

func (c QuoteClient) GetRealtimeQuote(symbols []Symbol) ([]*RealTimeQuote, error)
Example
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([]longbridge.Symbol{"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)
}
Output:

func (QuoteClient) GetRealtimeWarrantQuote

func (c QuoteClient) GetRealtimeWarrantQuote(symbols []Symbol) ([]*RealtimeWarrantQuote, error)
Example
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.GetRealtimeWarrantQuote([]longbridge.Symbol{"21125.HK"})
if err != nil {
	log.Fatalf("Error getting real time warrant quote: %v", err)
}
for _, q := range qs {
	log.Printf("%#v\n", q)
}
Output:

func (QuoteClient) GetStaticInfo

func (c QuoteClient) GetStaticInfo(symbols []Symbol) ([]*StaticInfo, error)
Example
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()
ss, err := c.GetStaticInfo([]longbridge.Symbol{"700.HK", "AAPL.US"})
if err != nil {
	log.Fatalf("Error getting static info: %v", err)
}
for _, s := range ss {
	log.Printf("%#v\n", s)
}
Output:

func (QuoteClient) GetSubscriptions

func (c QuoteClient) GetSubscriptions() ([]*QotSubscription, error)
Example
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()
ss, err := c.GetSubscriptions()
if err != nil {
	log.Fatalf("Error getting subscription list: %v", err)
}
for _, s := range ss {
	log.Printf("%#v", s)
}
Output:

func (QuoteClient) GetTickers

func (c QuoteClient) GetTickers(symbol Symbol, count int) ([]*Ticker, error)
Example
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)
}
Output:

func (QuoteClient) GetTradeDates

func (c QuoteClient) GetTradeDates(market Market, begin string, end string) ([]TradeDate, error)

GetTradeDates returns the trading days in given time range for the market. The begin and end are encoded as "20060102" format. The trading days are sorted in ascending time order. Note: The interval cannot be greater than one month. Only supports query data of the most recent year

Example
c, err := longbridge.NewQuoteClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
ds, err := c.GetTradeDates("HK", "20220530", "20220630")
if err != nil {
	log.Fatalf("Error getting trade date list: %v", err)
}
for _, d := range ds {
	log.Printf("%#v", d)
}
Output:

func (QuoteClient) GetWarrantIssuers

func (c QuoteClient) GetWarrantIssuers() ([]*Issuer, error)
Example
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()
is, err := c.GetWarrantIssuers()
if err != nil {
	log.Fatalf("Error getting warrant issuer list: %v", err)
}
for _, i := range is {
	log.Printf("%#v", i)
}
Output:

func (*QuoteClient) GetWatchedGroups

func (c *QuoteClient) GetWatchedGroups() ([]*WatchedGroup, error)
Example
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()
groups, err := c.GetWatchedGroups()
if err != nil {
	log.Fatalf("Error getting watched groups: %v", err)
}
for _, g := range groups {
	log.Printf("%v %v: %v", g.ID, g.Name, g.Securities)
}
Output:

func (QuoteClient) RefreshAccessToken

func (c QuoteClient) RefreshAccessToken(expire time.Time) (*AccessTokenInfo, error)

func (QuoteClient) SearchWarrants

func (c QuoteClient) SearchWarrants(cond *WarrantFilter) ([]*Warrant, error)
Example
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()
ws, err := c.SearchWarrants(&longbridge.WarrantFilter{
	Symbol:     "700.HK",
	Language:   longbridge.SimplifiedChinese,
	SortBy:     0,
	SortOrder:  1,
	SortOffset: 1,
	PageSize:   10,
})
if err != nil {
	log.Fatalf("Error searching warrants: %v", err)
}
for _, w := range ws {
	log.Printf("%#v", w)
}
Output:

func (QuoteClient) SubscribePush

func (c QuoteClient) SubscribePush(symbols []Symbol, subTypes []SubscriptionType, needFirstPush bool) ([]*QotSubscription, error)
Example
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)
	}
}
c.OnPushQuote = func(q *longbridge.PushQuote) {
	log.Printf("Got realtime quote: %#v", q)
}

c.OnPushBrokers = func(b *longbridge.PushBrokers) {
	log.Printf("Got broker list for %s, seq=%d", b.Symbol, b.Sequence)
	for _, bid := range b.Bid {
		log.Printf("%#v", bid)
	}
	for _, ask := range b.Ask {
		log.Printf("%#v", ask)
	}
}

c.OnPushOrderBook = func(b *longbridge.PushOrderBook) {
	log.Printf("Got order books for %s, seq=%d", b.Symbol, b.Sequence)
	for _, bid := range b.Bid {
		log.Printf("%#v", bid)
	}
	for _, ask := range b.Ask {
		log.Printf("%#v", ask)
	}
}

ss, err := c.SubscribePush([]longbridge.Symbol{"AAPL.US"},
	[]longbridge.SubscriptionType{longbridge.SubscriptionTicker,
		longbridge.SubscriptionRealtimeQuote,
		longbridge.SubscriptionOrderBook,
		longbridge.SubscriptionBrokerQueue}, 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,
		longbridge.SubscriptionRealtimeQuote,
		longbridge.SubscriptionOrderBook,
		longbridge.SubscriptionBrokerQueue}, true); err != nil {
	log.Fatalf("Error unsubscribing all symbols' quote push: %v", err)
}
Output:

func (QuoteClient) UnsubscribePush

func (c QuoteClient) UnsubscribePush(symbols []Symbol, subTypes []SubscriptionType, all bool) error

Unsubscribe clears the subscription given by symbols. If symbols is empty and all is true, it will clear the requested subscriptions for all subscribed symbols.

type RealTimeQuote

type RealTimeQuote struct {
	Symbol          Symbol
	LastDone        float64
	PrevClose       float64
	Open            float64
	High            float64
	Low             float64
	Timestamp       int64
	Volume          int64
	Turnover        float64
	PreMarketQuote  *PreMarketQuote
	PostMarketQuote *PostMarketQuote
}

type RealtimeOptionQuote

type RealtimeOptionQuote struct {
	Symbol       Symbol
	LastDone     float64
	PrevClose    float64
	Open         float64
	High         float64
	Low          float64
	Timestamp    int64
	Volume       int64
	Turnover     float64
	OptionExtend *OptionExtend
}

type RealtimeWarrantQuote

type RealtimeWarrantQuote struct {
	Symbol        Symbol
	LastDone      float64
	PrevClose     float64
	Open          float64
	High          float64
	Low           float64
	Timestamp     int64
	Volume        int64
	Turnover      float64
	WarrantExtend *WarrantExtended
}

type Request

type Request struct {
	Cmd  uint32
	Body proto.Message
}

type RiskLevel

type RiskLevel int
const (
	Low RiskLevel = iota + 1
	LowToMedium
	Medium
	MediumToHigh
	High
)

type SecurityFinanceIndex

type SecurityFinanceIndex struct {
	Symbol                Symbol
	LastDone              float64
	ChangeVal             float64
	ChangeRate            float64
	Volume                int64
	Turnover              float64
	YtdChangeRate         float64
	TurnoverRate          float64
	TotalMarketValue      float64
	CapitalFlow           float64
	Amplitude             float64
	VolumeRatio           float64
	PeTtmRatio            float64
	PbRatio               float64
	DividendRatioTtm      float64
	FiveDayChangeRate     float64
	TenDayChangeRate      float64
	HalfYearChangeRate    float64
	FiveMinutesChangeRate float64
	ExpiryDate            string
	StrikePrice           float64
	UpperStrikePrice      float64
	LowerStrikePrice      float64
	OutstandingQty        int64
	OutstandingRatio      float64
	Premium               float64
	ItmOtm                float64
	ImpliedVolatility     float64
	WarrantDelta          float64
	CallPrice             float64
	ToCallPrice           float64
	EffectiveLeverage     float64
	LeverageRatio         float64
	ConversionRatio       float64
	BalancePoint          float64
	OpenInterest          int64
	Delta                 float64
	Gamma                 float64
	Theta                 float64
	Vega                  float64
	Rho                   float64
}

type StaticInfo

type StaticInfo struct {
	Symbol            Symbol
	NameCn            string
	NameEn            string
	NameHk            string
	Exchange          string
	Currency          string
	LotSize           int32
	TotalShares       int64
	CirculatingShares int64
	HkShares          int64
	Eps               float64
	EpsTtm            float64
	Bps               float64
	DividendYield     float64
	StockDerivatives  []int32
	Board             string
}

type StockPosition

type StockPosition struct {
	Symbol            Symbol
	SymbolName        string
	Currency          string
	Quantity          uint64
	AvailableQuantity int64
	// CostPrice is cost price according to the TradeClient's choice of average purchase or diluted cost
	CostPrice      float64
	AccountChannel string
}

type StrikePriceInfo

type StrikePriceInfo struct {
	Price      float64
	CallSymbol string
	PutSymbol  string
	Standard   bool
}

type SubscriptionType

type SubscriptionType = quote.SubType

type Symbol

type Symbol string

Symbol is a stock symbol (of format <StockCode>.<Market>) or fund symbol (ISIN format)

func MakeSymbol

func MakeSymbol(stockCode string, market Market) Symbol

MakeSymbol creates a stock symbol from stock code and market.

func (Symbol) ToStock

func (s Symbol) ToStock() (string, Market, error)

ToStock converts stock symbol into stock code and market.

type Ticker

type Ticker struct {
	Price        float64
	Volume       int64
	Timestamp    int64
	TradeType    string
	Dir          TradeDir
	TradeSession TradeSessionType
}

type TimeInForce

type TimeInForce string

type TradeClient

type TradeClient struct {
	// contains filtered or unexported fields
}

func NewTradeClient

func NewTradeClient(conf *Config) (*TradeClient, error)

func (*TradeClient) CancelOrder

func (c *TradeClient) CancelOrder(orderID string) error

CancelOrder cancels an open order.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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.CancelOrder(orderID); err != nil {
	log.Fatalf("Error cancelling submitted order (id: %v): %v", orderID, err)
}

log.Printf("Order cancelled successfully, ID: %v", orderID)
Output:

func (*TradeClient) Close

func (c *TradeClient) Close()

func (TradeClient) Enable

func (c TradeClient) Enable(enable bool)
Example
// Before running the example, set the access key, app key and app secret in the env. i.e.,
// export LB_ACCESS_TOKEN="<your access token>"
// export LB_APP_KEY="<your app key>"
// export LB_APP_SECRET="<your app secret>"
// Then run with command to see the detailed log.
// go test -v -run ExampleTradeClient_Enable -args -logtostderr -v=4
c, err := NewTradeClient(&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)
}
c.OnOrderChange = func(order *Order) {
	log.Printf("Got order: %#v\n", order)
}
c.Enable(true)
time.Sleep(11 * time.Second)
log.Println("Start to close subscription")
c.Enable(false)
time.Sleep(10 * time.Second)
log.Println("Start to re-enable subscription")
c.Enable(true)
time.Sleep(15 * time.Second)
log.Println("Closing")
c.Close()
Output:

func (*TradeClient) GetAccountBalances

func (c *TradeClient) GetAccountBalances() ([]*Balance, error)

GetAccountBalances get account balances.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
balances, err := c.GetAccountBalances()
if err != nil {
	log.Fatalf("Error getting account balance: %v", err)
}
for _, b := range balances {
	log.Printf("%+v", b)
}
Output:

func (*TradeClient) GetCashflows

func (c *TradeClient) GetCashflows(r *CashflowReq) ([]*Cashflow, error)

GetCashflows get cash flows of an account.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
cs, err := c.GetCashflows(&longbridge.CashflowReq{
	StartTimestamp: time.Now().AddDate(-1, 0, 0).Unix(),
	EndTimestamp:   time.Now().Unix()})
if err != nil {
	log.Fatalf("Error getting account cash flow: %v", err)
}
for _, c := range cs {
	log.Printf("%+v\n", c)
}
Output:

func (*TradeClient) GetFundPositions

func (c *TradeClient) GetFundPositions(fundSymbols ...Symbol) ([]*FundPosition, error)

GetFundPositions gets fund positions. Fund symbols are optional.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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.GetFundPositions()
if err != nil {
	log.Fatalf("Error getting fund positions: %v", err)
}
for _, position := range positions {
	log.Printf("%+v", position)
}
Output:

func (*TradeClient) GetHistoryOrderFills

func (c *TradeClient) GetHistoryOrderFills(r *GetHistoryOrderFillsReq) ([]*OrderFill, error)

GetHistoryOrderFills gets history order fills in ascending trade completion time.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
os, err := c.GetHistoryOrderFills(&longbridge.GetHistoryOrderFillsReq{
	Symbol:         "",
	StartTimestamp: time.Now().AddDate(-1, 0, 0).Unix(),
	EndTimestamp:   time.Now().Unix(),
})
if err != nil {
	log.Fatalf("Error getting history order fills: %v", err)
}
for _, o := range os {
	log.Printf("%+v\n", o)
}
Output:

func (*TradeClient) GetHistoryOrders

func (c *TradeClient) GetHistoryOrders(r *GetHistoryOrdersReq) ([]*Order, error)

GetHistoryOrders get history orders in ascending update time order.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
os, err := c.GetHistoryOrders(&longbridge.GetHistoryOrdersReq{
	Symbol:         "",
	Status:         nil,
	Side:           "",
	Market:         longbridge.HK,
	StartTimestamp: time.Now().AddDate(-1, 0, 0).Unix(),
	EndTimestamp:   time.Now().Unix(),
})
if err != nil {
	log.Fatalf("Error getting history orders: %v", err)
}
for _, o := range os {
	log.Printf("%+v\n", o)
}
Output:

func (*TradeClient) GetMarginRatio

func (c *TradeClient) GetMarginRatio(symbol Symbol) (*MarginRatio, error)
Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
mr, err := c.GetMarginRatio("700.HK")
if err != nil {
	log.Fatalf("Error getting margin ratio: %v", err)
}
log.Printf("%#v", mr)
Output:

func (*TradeClient) GetStockPositions

func (c *TradeClient) GetStockPositions(symbols ...Symbol) ([]*StockPosition, error)

GetStockPositions gets stock positions. If stock symbols are provided, only the positions matching the symbols will be returned. If stocks symbols are left empty, all account positions will be returned.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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)
}
Output:

func (*TradeClient) GetTodayOrderFills

func (c *TradeClient) GetTodayOrderFills(r *GetTodayOrderFillsReq) ([]*OrderFill, error)

GetTodayOrderFills get today order fills in ascending trade done time.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
os, err := c.GetTodayOrderFills(&longbridge.GetTodayOrderFillsReq{
	Symbol:  "",
	OrderID: 0,
})
if err != nil {
	log.Fatalf("Error getting today's order fills: %v", err)
}
for _, o := range os {
	log.Printf("%+v\n", o)
}
Output:

func (*TradeClient) GetTodayOrders

func (c *TradeClient) GetTodayOrders(r *GetTodyOrdersReq) ([]*Order, error)

GetTodayOrders get today orders in ascending update time order.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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()
os, err := c.GetTodayOrders(&longbridge.GetTodyOrdersReq{
	Symbol:  "",
	Status:  nil,
	Side:    "",
	Market:  longbridge.US,
	OrderID: 0,
})
if err != nil {
	log.Fatalf("Error getting today's orders: %v", err)
}
for _, o := range os {
	log.Printf("%+v\n", o)
}
Output:

func (*TradeClient) ModifyOrder

func (c *TradeClient) ModifyOrder(r *ModifyOrderReq) error

ModifyOrder modifies an order. Order ID and quantity are required.

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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)
Output:

func (*TradeClient) PlaceOrder

func (c *TradeClient) PlaceOrder(r *PlaceOrderReq) (string, error)

PlaceOrder places an order. It returns order ID and error (if any).

Example
c, err := longbridge.NewTradeClient(&longbridge.Config{
	BaseURL:       "https://openapi.longbridgeapp.com",
	AccessToken:   os.Getenv("LB_ACCESS_TOKEN"),
	QuoteEndpoint: "tcp://openapi-quote.longbridgeapp.com:2020",
	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)
}
log.Printf("Order submitted successfully, ID: %v", orderID)
Output:

func (TradeClient) RefreshAccessToken

func (c TradeClient) RefreshAccessToken(expire time.Time) (*AccessTokenInfo, error)

func (TradeClient) Subscribe

func (c TradeClient) Subscribe(topics []string) error

Subscribe subscribes the topic for push notification. Currently for trade API only "private" has effect.

func (TradeClient) Unsubscribe

func (c TradeClient) Unsubscribe(topics []string) error

type TradeDate

type TradeDate struct {
	Date          string
	TradeDateType int32 // 0 full day, 1 morning only, 2 afternoon only(not happened before)
}

type TradeDir

type TradeDir int32

type TradeSessionType

type TradeSessionType = quote.TradeSession

type TradeStatus

type TradeStatus = quote.TradeStatus

type TrdSide

type TrdSide string

type TriggerStatus

type TriggerStatus string

type Warrant

type Warrant struct {
	Symbol            Symbol
	Name              string
	LastDone          float64
	ChangeRate        float64
	ChangeVal         float64
	Turnover          float64
	ExpiryDate        string // YYYYMMDD
	StrikePrice       float64
	UpperStrikePrice  float64
	LowerStrikePrice  float64
	OutstandingQty    float64
	OutstandingRatio  float64
	Premium           float64
	ItmOtm            float64
	ImpliedVolatility float64
	Delta             float64
	CallPrice         float64
	EffectiveLeverage float64
	LeverageRatio     float64
	ConversionRatio   float64
	BalancePoint      float64
	State             string
}

type WarrantExtended

type WarrantExtended struct {
	ImpliedVolatility float64
	ExpiryDate        string
	LastTradeDate     string
	OutstandingRatio  float64
	OutstandingQty    int64
	ConversionRatio   float64
	Category          string
	StrikePrice       float64
	UpperStrikePrice  float64
	LowerStrikePrice  float64
	CallPrice         float64
	UnderlyingSymbol  string
}

type WarrantFilter

type WarrantFilter struct {
	Symbol   Symbol
	Language Language

	SortBy     int32
	SortOrder  int32 // 0 Ascending 1 Desending
	SortOffset int32
	PageSize   int32 // Up to 500

	Type      []int32 // optional values: 0 - Call	1 - Put 2 - Bull 3 - Bear 4 - Inline
	IssuerIDs []int32

	// ExpiryDateType can have the following values.
	// 1 - Less than 3 months
	// 2 - 3 - 6 months
	// 3 - 6 - 12 months
	// 4 - greater than 12 months
	ExpiryDateType []int32

	// Optional values for PriceType
	// 1 - In bounds
	// 2 - Out bounds
	PriceType []int32

	// Optional values for Status:
	// 2 - Suspend trading
	// 3 - Papare List
	// 4 - Normal
	Status []int32
}

WarrantFilter includes the search conditions for warrants. The field defintion can refer to https://open.longbridgeapp.com/en/docs/quote/pull/warrant-filter

type WatchedGroup

type WatchedGroup struct {
	ID         string
	Name       string
	Securities []*WatchedSecurity
}

type WatchedSecurity

type WatchedSecurity struct {
	Symbol       Symbol
	Name         string
	WatchedPrice float64
	WatchedAt    int64
}

func (*WatchedSecurity) String

func (wg *WatchedSecurity) String() string

Directories

Path Synopsis
internal
protocol
Package protocol provides the binary encoding/decoding for long bridge communication protocol.
Package protocol provides the binary encoding/decoding for long bridge communication protocol.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL