func (c *Client) SubscribeCandles(ctx context.Context, symbol string, resolution common.CandleResolution) (string, error) {
	req := &SubscriptionRequest{
		SubID:   c.nonce.GetNonce(),
		Event:   EventSubscribe,
		Channel: ChanCandles,
		Key:     fmt.Sprintf("trade:%s:%s", resolution, symbol),
	}
	return c.Subscribe(ctx, req)
}
Submit a subscription request to receive candle updates
package websocket
import (
	"context"
	"fmt"
	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/book"
	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/common"
	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/fundingcredit"
	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/fundingloan"
	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/fundingoffer"
	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/order"
)
type FlagRequest struct {
	Event string `json:"event"`
	Flags int    `json:"flags"`
}
func (c *Client) Send(ctx context.Context, msg interface{}) error {
	socket, err := c.getSocket()
	if err != nil {
		return err
	}
	return socket.Asynchronous.Send(ctx, msg)
}
func (c *Client) EnableFlag(ctx context.Context, flag int) (string, error) {
	req := &FlagRequest{
		Event: "conf",
		Flags: flag,
	}
	socks := make([]*Socket, len(c.sockets))
	c.mtx.RLock()
	for i, socket := range c.sockets {
		socks[i] = socket
	}
	c.mtx.RUnlock()
	for _, socket := range socks {
		err := socket.Asynchronous.Send(ctx, req)
		if err != nil {
			return "", err
		}
	}
	return "", nil
}
func (c *Client) ConnectionCount() int {
	c.mtx.RLock()
	defer c.mtx.RUnlock()
	return len(c.sockets)
}
func (c *Client) AvailableCapacity() int {
	return c.getTotalAvailableSocketCapacity()
}
func (c *Client) StartNewConnection() error {
	return c.connectSocket(SocketId(c.ConnectionCount()))
}
func (c *Client) subscribeBySocket(ctx context.Context, socket *Socket, req *SubscriptionRequest) (string, error) {
	c.subscriptions.add(socket.Id, req)
	err := socket.Asynchronous.Send(ctx, req)
	if err != nil {
		return "", err
	}
	return req.SubID, nil
}
func (c *Client) Subscribe(ctx context.Context, req *SubscriptionRequest) (string, error) {
	if c.getTotalAvailableSocketCapacity() <= 1 {
		err := c.StartNewConnection()
		if err != nil {
			return "", err
		}
	}
	socket, err := c.getMostAvailableSocket()
	if err != nil {
		return "", err
	}
	return c.subscribeBySocket(ctx, socket, req)
}
func (c *Client) SubscribeTicker(ctx context.Context, symbol string) (string, error) {
	req := &SubscriptionRequest{
		SubID:   c.nonce.GetNonce(),
		Event:   EventSubscribe,
		Channel: ChanTicker,
		Symbol:  symbol,
	}
	return c.Subscribe(ctx, req)
}
func (c *Client) SubscribeTrades(ctx context.Context, symbol string) (string, error) {
	req := &SubscriptionRequest{
		SubID:   c.nonce.GetNonce(),
		Event:   EventSubscribe,
		Channel: ChanTrades,
		Symbol:  symbol,
	}
	return c.Subscribe(ctx, req)
}
func (c *Client) SubscribeBook(ctx context.Context, symbol string, precision common.BookPrecision, frequency common.BookFrequency, priceLevel int) (string, error) {
	if priceLevel < 0 {
		return "", fmt.Errorf("negative price levels not supported: %d", priceLevel)
	}
	req := &SubscriptionRequest{
		SubID:     c.nonce.GetNonce(),
		Event:     EventSubscribe,
		Channel:   ChanBook,
		Symbol:    symbol,
		Precision: string(precision),
		Len:       fmt.Sprintf("%d", priceLevel),  
	}
	if !book.IsRawBook(string(precision)) {
		req.Frequency = string(frequency)
	}
	return c.Subscribe(ctx, req)
}