td

package module
v0.0.0-...-04af2e1 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2025 License: MIT Imports: 19 Imported by: 0

README

td

TD ameritrade API client (now schwab)

go get github.com/AnthonyHewins/td # requires >= go1.24

Disclaimers

Schwab's API has many things it does that contradict the documentation. There are many times I had to manually write code to spec and run it only to see that something was very wrong. As it stands, everything is correct rather than matching what their docs say. If changes come along server side, this client may be incorrect in certain things

Known areas:

  • ChartFuture fields are completely out of order

Usage

The API as it stands is not the nicest. I can't offer the greatest dev experience, but I tried. Currently the only supported functionality is streaming data. To stream data, you'll need the websocket

To use the websocket:

  1. Get all your credentials in order. As of right now that means client key/secret and also fetching a refresh token every 7 days manually (what a horrible pain)
  2. Create the HTTPClient whose sole existence is to fetch the information needed to connect to the socket
  3. Pass an enormous amount of information to the NewSocket function to handle far too much logic than should be needed for a login

Then you're ready to go

hc := td.New( // HTTP client
	td.ProdURL,
	td.AuthUrl,
	"client-key",
	"client-secret",
	// td.WithClientLogger(slog.Handler),
	// td.WithHTTPAccessToken(cachedTokenIfYouHaveIt),
)

t, err = hc.Authenticate(ctx, conf.RefreshToken)
if err != nil { panic("") }

ws, err := td.NewSocket(
	ctx, // master context. When this is canceled, it shuts everything down
	nil, // websocket dial options, not required
	hc, // the HTTP client
	t.RefreshToken,
	// td.WithLogger(logger),
	// td.WithTimeout(timeout),
	// td.WithEquityHandler(),
	// td.WithOptionHandler(),
	// td.WithFutureHandler(),
	// td.WithFutureOptionHandler(),
	// td.WithChartEquityHandler(),
	// td.WithChartFutureHandler(),
	td.WithErrHandler(func (err error) {
		// if there is a disconnect, you'll get an error wrapped in net.ErrClosed
		if errors.Is(err, net.ErrClosed) {
			// trigger reconnect, log, whatever
		}

		panic(err)
	})
)

How the socket works

Under the hood

The websocket acts like a regular client. Under the hood though, it does several things:

  • Starts a goroutine to handle pings at regular intervals
  • Starts a goroutine to handle constant reads from the websocket, so you're always listening for the next message; when a message is received, it gets pushed to the channel in the below goroutine
  • Starts a goroutine whose sole job is to deserialize the message received from the above goroutine and then route it to the correct spot since messages come in out of order
Calling methods on the socket

Calling methods on the socket works just like any regular code. Call the method, get the response or an error

  • Responses are routed from the code mentioned above in the goroutine that routes the response back to you
  • Errors that occur from a method call will not propagate to the error handler you pass in
Observability

These 3 goroutines can witness lots of errors, so it's important that if you want good visibility that you at least use WihtErrHandler that routes errors to a handler you make. In addition you can handle server pong messages with another handler this package offers

Disconnects

When there's a disconnect event that the server initiated, that happens in the goroutines that manage the reader of the socket. To propagate that event to your code, it gets passed to the error handler in WithErrHandler. Whenever there's a disconnect event, the error sent will be wrapped with net.ErrClosed which you can test for using errors.Is(err, net.ErrClosed) in standard Go fashion

If you cancel the context passed during creation, no error will be sent because this was initiated by you

TODOs

  • Figure out the absymal documentation on these things:
    • FutureTradingHours field
    • FuturePriceFormat

Documentation

Index

Constants

View Source
const (
	AuthUrl = "https://api.schwabapi.com/v1/oauth/token"
	ProdURL = "https://api.schwabapi.com/trader/v1"
)
View Source
const (
	DefaultWSTimeout = 5 * time.Second
	DefaultPingEvery = 3 * time.Second
)

Variables

View Source
var (
	ErrMissingPeriodType    = errors.New("missing period type")
	ErrMissingFrequencyType = errors.New("missing frequency type")
	ErrMissingSymbol        = errors.New("missing symbol")
	ErrInvalidSymbol        = errors.New("symbols must be 5 characters or less")
	ErrMissingReq           = errors.New("missing request object")
)
View Source
var (
	ErrMissingWSSUrl    = errors.New("received empty string for websocket connection URL")
	ErrMissingUserCreds = errors.New("missing user credentials for socket login, one or more values empty/zero value")
)
View Source
var (
	ErrMissingExpiration  = errors.New("missing expiration")
	ErrInvalidSide        = errors.New("missing option side (one of call,put)")
	ErrInvalidStrike      = errors.New("strike price must be >0")
	ErrMissingOptions     = errors.New("missing options")
	ErrInvalidOptionID    = errors.New("invalid option ID")
	ErrInvalidOptionField = errors.New("invalid option field")
)
View Source
var (
	ErrBufferManagerForcedTimeout = errors.New("buffer manager closed request; it timed out")
)
View Source
var (
	ErrForceShutdown = errors.New("shutdown frame received")
)
View Source
var (
	ErrMissingAcctIDs = errors.New("missing account IDs")
)
View Source
var ErrMissingField = errors.New("missing field(s)")
View Source
var ErrMissingRefresh = errors.New(`refresh token is currently required to authenticate.
Spam schwab emails and tell them this is stupid and they should follow automated authentication`)

Functions

func AssetSubtypeStrings

func AssetSubtypeStrings() []string

AssetSubtypeStrings returns a slice of all String values of the enum

func AssetTypeStrings

func AssetTypeStrings() []string

AssetTypeStrings returns a slice of all String values of the enum

func ChartEquityFieldStrings

func ChartEquityFieldStrings() []string

ChartEquityFieldStrings returns a slice of all String values of the enum

func ChartFutureFieldStrings

func ChartFutureFieldStrings() []string

ChartFutureFieldStrings returns a slice of all String values of the enum

func ConnStatusStrings

func ConnStatusStrings() []string

ConnStatusStrings returns a slice of all String values of the enum

func EquityFieldStrings

func EquityFieldStrings() []string

EquityFieldStrings returns a slice of all String values of the enum

func ExchangeIDStrings

func ExchangeIDStrings() []string

ExchangeIDStrings returns a slice of all String values of the enum

func FrequencyTypeStrings

func FrequencyTypeStrings() []string

FrequencyTypeStrings returns a slice of all String values of the enum

func FutureFieldStrings

func FutureFieldStrings() []string

FutureFieldStrings returns a slice of all String values of the enum

func FutureOptionFieldStrings

func FutureOptionFieldStrings() []string

FutureOptionFieldStrings returns a slice of all String values of the enum

func OptionFieldStrings

func OptionFieldStrings() []string

OptionFieldStrings returns a slice of all String values of the enum

func PeriodTypeStrings

func PeriodTypeStrings() []string

PeriodTypeStrings returns a slice of all String values of the enum

func SecurityStatusStrings

func SecurityStatusStrings() []string

SecurityStatusStrings returns a slice of all String values of the enum

func UserPrincipalFieldStrings

func UserPrincipalFieldStrings() []string

UserPrincipalFieldStrings returns a slice of all String values of the enum

func WSRespCodeStrings

func WSRespCodeStrings() []string

WSRespCodeStrings returns a slice of all String values of the enum

Types

type AssetSubtype

type AssetSubtype byte
const (
	AssetSubtypeUnspecified AssetSubtype = iota
	AssetSubtypeADR
	AssetSubtypeCEF
	AssetSubtypeCOE
	AssetSubtypeETF
	AssetSubtypeETN
	AssetSubtypeGDR
	AssetSubtypeOEF
	AssetSubtypePRF
	AssetSubtypeRGT
	AssetSubtypeUIT
	AssetSubtypeWAR
)

func AssetSubtypeString

func AssetSubtypeString(s string) (AssetSubtype, error)

AssetSubtypeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func AssetSubtypeValues

func AssetSubtypeValues() []AssetSubtype

AssetSubtypeValues returns all values of the enum

func (AssetSubtype) IsAAssetSubtype

func (i AssetSubtype) IsAAssetSubtype() bool

IsAAssetSubtype returns "true" if the value is listed in the enum definition. "false" otherwise

func (AssetSubtype) MarshalJSON

func (i AssetSubtype) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for AssetSubtype

func (AssetSubtype) String

func (i AssetSubtype) String() string

func (*AssetSubtype) UnmarshalJSON

func (i *AssetSubtype) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for AssetSubtype

type AssetType

type AssetType byte
const (
	AssetTypeUnspecified AssetType = iota
	AssetTypeBond
	AssetTypeEquity
	AssetTypeEtf
	AssetTypeExtended
	AssetTypeForex
	AssetTypeFuture
	AssetTypeFutureOption
	AssetTypeFundamental
	AssetTypeIndex
	AssetTypeIndicator
	AssetTypeMutualFund
	AssetTypeOption
	AssetTypeUnknown
)

func AssetTypeString

func AssetTypeString(s string) (AssetType, error)

AssetTypeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func AssetTypeValues

func AssetTypeValues() []AssetType

AssetTypeValues returns all values of the enum

func (AssetType) IsAAssetType

func (i AssetType) IsAAssetType() bool

IsAAssetType returns "true" if the value is listed in the enum definition. "false" otherwise

func (AssetType) MarshalJSON

func (i AssetType) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for AssetType

func (AssetType) String

func (i AssetType) String() string

func (*AssetType) UnmarshalJSON

func (i *AssetType) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for AssetType

type Authorizations

type Authorizations struct {
	Apex               bool   `json:"apex"`
	LevelTwoQuotes     bool   `json:"levelTwoQuotes"`
	StockTrading       bool   `json:"stockTrading"`
	MarginTrading      bool   `json:"marginTrading"`
	StreamingNews      bool   `json:"streamingNews"`
	OptionTradingLevel string `json:"optionTradingLevel"`
	StreamerAccess     bool   `json:"streamerAccess"`
	AdvancedMargin     bool   `json:"advancedMargin"`
	ScottradeAccount   bool   `json:"scottradeAccount"`
}

type Candle

type Candle struct {
	Close    float64 `json:"close"`
	Datetime int     `json:"datetime"`
	High     float64 `json:"high"`
	Low      float64 `json:"low"`
	Open     float64 `json:"open"`
	Volume   float64 `json:"volume"`
}

type ChartEquity

type ChartEquity struct {
	Symbol     string
	OpenPrice  float64
	HighPrice  float64
	LowPrice   float64
	ClosePrice float64
	Volume     float64
	Sequence   int
	Time       time.Time
	Day        int
}

func (*ChartEquity) UnmarshalJSON

func (c *ChartEquity) UnmarshalJSON(b []byte) error

type ChartEquityField

type ChartEquityField byte
const (
	ChartFieldSymbol ChartEquityField = iota
	ChartFieldOpenPrice
	ChartFieldHighPrice
	ChartFieldLowPrice
	ChartFieldClosePrice
	ChartFieldVolume
	ChartFieldSequence
	ChartFieldTime
	ChartFieldDay
)

func ChartEquityFieldString

func ChartEquityFieldString(s string) (ChartEquityField, error)

ChartEquityFieldString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func ChartEquityFieldValues

func ChartEquityFieldValues() []ChartEquityField

ChartEquityFieldValues returns all values of the enum

func (ChartEquityField) IsAChartEquityField

func (i ChartEquityField) IsAChartEquityField() bool

IsAChartEquityField returns "true" if the value is listed in the enum definition. "false" otherwise

func (ChartEquityField) String

func (i ChartEquityField) String() string

type ChartEquityReq

type ChartEquityReq struct {
	Symbols []string
	Fields  []ChartEquityField
}

func (*ChartEquityReq) MarshalJSON

func (f *ChartEquityReq) MarshalJSON() ([]byte, error)

type ChartFuture

type ChartFuture struct {
	Symbol     string    `json:"0"` // Ticker symbol in upper case.	N/A	N/A
	Time       time.Time `json:"1"`
	OpenPrice  float64   `json:"2"` // double	Opening price for the minute	Yes	Yes
	HighPrice  float64   `json:"3"` // double	Highest price for the minute	Yes	Yes
	LowPrice   float64   `json:"4"` // double	Chart's lowest price for the minute	Yes	Yes
	ClosePrice float64   `json:"5"` // double	Closing price for the minute	Yes	Yes
	Volume     float64   `json:"6"` // Total volume for the minute	Yes	Yes
}

func (*ChartFuture) UnmarshalJSON

func (c *ChartFuture) UnmarshalJSON(b []byte) error

type ChartFutureField

type ChartFutureField byte
const (
	ChartFutureFieldSymbol ChartFutureField = iota
	ChartFutureFieldTime
	ChartFutureFieldOpenPrice
	ChartFutureFieldHighPrice
	ChartFutureFieldLowPrice
	ChartFutureFieldClosePrice
	ChartFutureFieldVolume
)

func ChartFutureFieldString

func ChartFutureFieldString(s string) (ChartFutureField, error)

ChartFutureFieldString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func ChartFutureFieldValues

func ChartFutureFieldValues() []ChartFutureField

ChartFutureFieldValues returns all values of the enum

func (ChartFutureField) IsAChartFutureField

func (i ChartFutureField) IsAChartFutureField() bool

IsAChartFutureField returns "true" if the value is listed in the enum definition. "false" otherwise

func (ChartFutureField) String

func (i ChartFutureField) String() string

type ChartFutureReq

type ChartFutureReq struct {
	Symbols []string
	Fields  []ChartFutureField
}

func (*ChartFutureReq) MarshalJSON

func (f *ChartFutureReq) MarshalJSON() ([]byte, error)

type ConnStatus

type ConnStatus byte
const (
	ConnStatusUnspecified ConnStatus = iota
	ConnStatusNonPro
	ConnStatusPro
)

func ConnStatusString

func ConnStatusString(s string) (ConnStatus, error)

ConnStatusString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func ConnStatusValues

func ConnStatusValues() []ConnStatus

ConnStatusValues returns all values of the enum

func (ConnStatus) IsAConnStatus

func (i ConnStatus) IsAConnStatus() bool

IsAConnStatus returns "true" if the value is listed in the enum definition. "false" otherwise

func (ConnStatus) MarshalText

func (i ConnStatus) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface for ConnStatus

func (ConnStatus) String

func (i ConnStatus) String() string

func (*ConnStatus) UnmarshalText

func (i *ConnStatus) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface for ConnStatus

type Equity

type Equity struct {
	// Key is the identifier that according to the docs is "usually the symbol"
	// so you should be able to get away with skipping passing the symbol as a field when
	// requesting data
	Key     string
	Type    AssetType
	Subtype AssetSubtype
	Cusip   string

	//	String	Ticker symbol in upper case.
	Symbol string

	BidPrice  float64
	AskPrice  float64
	LastPrice float64

	// Units are "lots" (typically 100 shares per lot)
	// Note for NFL data this field can be 0 with a non-zero bid price which representing a bid size of less than 100 shares.
	BidSize int
	AskSize int

	// ID of the exchange with the ask/bid (datatype of char)
	AskID rune
	BidID rune

	TotalVolume int // Aggregated shares traded throughout the day, including pre/post market hours. Volume is set to zero at 7:28am ET.
	LastSize    int // Number of shares traded with last trade; units are shares

	// According to industry standard, only regular session trades set the High and Low
	// If a stock does not trade in the regular session, high and low will be zero.
	// High/low reset to ZERO at 3:30am ET
	HighPrice float64
	LowPrice  float64

	ClosePrice float64 // Closing prices are updated from the DB at 3:30 AM ET.

	// As long as the symbol is valid, this data is always present
	// This field is updated every time the closing prices are loaded from DB
	//
	ExchangeID ExchangeID

	Marginable  bool       // Stock approved by the Federal Reserve and an investor's broker as being eligible for providing collateral for margin debt.
	Description string     // A company, index or fund name	Once per day descriptions are loaded from the database at 7:29:50 AM ET.
	LastID      ExchangeID // Exchange where last trade was executed

	// Day's Open Price According to industry standard, only regular session trades set the open.
	// If a stock does not trade during the regular session, then the open price is 0.
	// In the pre-market session, open is blank because pre-market session trades do not set the open.
	// Open is set to ZERO at 3:30am ET.
	OpenPrice float64

	NetChange float64 // NetChange = LastPrice - ClosePrice. If close is zero, change will be zero

	High52Week float64 // Higest price traded in the past 12 months, or 52 weeks. Calculated by merging intraday high (from fh) and 52-week high (from db)
	Low52Week  float64 // Lowest price traded in the past 12 months, or 52 weeks. Calculated by merging intraday low (from fh) and 52-week low (from db)

	// The P/E equals the price of a share of stock, divided by the companys
	// earnings-per-share.	Note that the "price of a share of stock" in the
	// definition does update during the day so this field has the potential to
	// stream. However, the current implementation uses the closing price and
	// therefore does not stream throughout the day.
	PERatio float64

	AnnualDividendAmount         float64
	DividendYield                float64
	NAV                          float64 // Mutual Fund Net Asset Value. Loads various times after market close
	ExchangeName                 string  // Display name of exchange
	DividendDate                 string
	RegularMarketQuote           bool      // Is last quote a regular quote
	RegularMarketTrade           bool      // Is last trade a regular trade
	RegularMarketLastPrice       float64   // Only records regular trade
	RegularMarketLastSize        int       // Currently realize/100, only records regular trade
	RegularMarketNetChange       float64   // RegularMarketLastPrice - ClosePrice
	SecurityStatus               string    // Indicates a symbols current trading status, Normal, Halted, Closed
	MarkPrice                    float64   // Mark Price
	QuoteTimeInLong              time.Time // Last time a bid or ask updated in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	TradeTimeInLong              time.Time // Last trade time in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	RegularMarketTradeTimeInLong time.Time // Regular market trade time in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	BidTime                      time.Time // Last bid time in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	AskTime                      time.Time // Last ask time in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	AskMicID                     string    // 4-chars Market Identifier Code
	BidMicID                     string    // 4-chars Market Identifier Code
	LastMicID                    string    // 4-chars Market Identifier Code
	NetPercentChange             float64   // Net Percentage Change = NetChange / ClosePrice * 100
	RegularMarketPercentChange   float64   // Regular market hours percentage change	RegularMarketNetChange / ClosePrice * 100
	MarkPriceNetChange           float64   // Mark price net change	7.97
	MarkPricePercentChange       float64   // Mark price percentage change	4.2358
	HardtoBorrowQuantity         int       // -1 = NULL   >=0 is valid quantity
	HardToBorrowRate             *float64  // null = NULL   valid range = -99,999.999 to +99,999.999
	HardtoBorrow                 int       // -1 = NULL 1 = true 0 = false
	Shortable                    int       // -1 = NULL  1 = true 0 = false
	PostMarketNetChange          float64   // Change in price since the end of the regular session (typically 4:00pm)	PostMarketLastPrice - RegularMarketLastPrice
	PostMarketPercentChange      float64   // Percent Change in price since the end of the regular session (typically 4:00pm)	PostMarketNetChange / RegularMarketLastPrice * 100

	// When false: data is from SIP.
	// SIP stands for Securities Information Processor. Often considered the
	// example for market data around the world, a SIP will collect trade and
	// quote data from multiple exchanges and consolidate these sources into a
	// single source of information.
	// When true: data is from an NFL source
	// NFL stands for Non-Fee Liable. This either means the result is returning
	// delayed data (typically options, futures and futures options) or the
	// result is returning real-time data from a subset of exchanges and
	// therefore does not contain all markets in the National Plan (typically
	// equity data). Delayed quotes do not represent the most recent last or
	// bid/ask; real-time quotes from the subset of exchanges may not contain
	// the most recent last or bid/ask.
	Delayed bool
}

func (*Equity) UnmarshalJSON

func (e *Equity) UnmarshalJSON(b []byte) error

type EquityField

type EquityField uint8
const (
	//	String	Ticker symbol in upper case.
	EquityFieldSymbol EquityField = 0

	EquityFieldBidPrice  EquityField = 1 // float64
	EquityFieldAskPrice  EquityField = 2 // float64
	EquityFieldLastPrice EquityField = 3 // float64

	// Units are "lots" (typically 100 shares per lot)
	// Note for NFL data this field can be 0 with a non-zero bid price which representing a bid size of less than 100 shares.
	EquityFieldBidSize EquityField = 4 // int
	EquityFieldAskSize EquityField = 5 // int

	// ID of the exchange with the ask/bid (datatype of char)
	EquityFieldAskID EquityField = 6
	EquityFieldBidID EquityField = 7

	EquityFieldTotalVolume EquityField = 8 // Aggregated shares traded throughout the day, including pre/post market hours.	Volume is set to zero at 7:28am ET.
	// Size	long	Number of shares traded with last trade	Units are shares
	// double	Day's high trade price	According to industry standard, only regular session trades set the High and Low
	// If a stock does not trade in the regular session, high and low will be zero.
	// High/low reset to ZERO at 3:30am ET
	EquityFieldLastSize EquityField = 9

	// According to industry standard, only regular session trades set the High and Low
	// If a stock does not trade in the regular session, high and low will be zero.
	// High/low reset to ZERO at 3:30am ET
	EquityFieldHighPrice EquityField = 10
	EquityFieldLowPrice  EquityField = 11

	// Closing prices are updated from the DB at 3:30 AM ET.
	EquityFieldClosePrice EquityField = 12 // double

	// As long as the symbol is valid, this data is always present
	// This field is updated every time the closing prices are loaded from DB
	//
	// Exchange	Code	Realtime/NFL
	// AMEX	A	Both
	// Indicator	:	Realtime Only
	// Indices	0	Realtime Only
	// Mutual Fund	3	Realtime Only
	// NASDAQ	Q	Both
	// NYSE	N	Both
	// Pacific	P	Both
	// Pinks	9	Realtime Only
	// OTCBB	U	Realtime Only
	EquityFieldExchangeID EquityField = 13 // char

	EquityFieldMarginable  EquityField = 14 //		boolean	Stock approved by the Federal Reserve and an investor's broker as being eligible for providing collateral for margin debt.
	EquityFieldDescription EquityField = 15 //		String	A company, index or fund name	Once per day descriptions are loaded from the database at 7:29:50 AM ET.
	EquityFieldLastID      EquityField = 16 //		char	Exchange where last trade was executed

	//	double	Day's Open Price According to industry standard, only regular session trades set the open.
	//
	// If a stock does not trade during the regular session, then the open price is 0.
	// In the pre-market session, open is blank because pre-market session trades do not set the open.
	// Open is set to ZERO at 3:30am ET.
	EquityFieldOpenPrice EquityField = 17

	EquityFieldNetChange EquityField = 18 //		double	 	LastPrice - ClosePrice If close is zero, change will be zero

	EquityField52WeekHigh EquityField = 19 //		double	Higest price traded in the past 12 months, or 52 weeks	Calculated by merging intraday high (from fh) and 52-week high (from db)
	EquityField52WeekLow  EquityField = 20 //		double	Lowest price traded in the past 12 months, or 52 weeks	Calculated by merging intraday low (from fh) and 52-week low (from db)

	// The P/E equals the price of a share of stock, divided by the companys earnings-per-share.	Note that the "price of a share of stock" in the definition does update during the day so this field has the potential to stream. However, the current implementation uses the closing price and therefore does not stream throughout the day.
	EquityFieldPERatio EquityField = 21 //		double	Price-to-earnings ratio.

	EquityFieldAnnualDividendAmount         EquityField = 22 //		double	Annual Dividend Amount
	EquityFieldDividendYield                EquityField = 23 //		double	Dividend Yield
	EquityFieldNAVEquityField                           = 24 //		double	Mutual Fund Net Asset Value	Load various times after market close
	EquityFieldExchangeName                 EquityField = 25 //		String	Display name of exchange
	EquityFieldDividendDate                 EquityField = 26 //		String
	EquityFieldRegularMarketQuote           EquityField = 27 //		boolean	 	Is last quote a regular quote
	EquityFieldRegularMarketTrade           EquityField = 28 //		boolean	 	Is last trade a regular trade
	EquityFieldRegularMarketLastPrice       EquityField = 29 //		double	 	Only records regular trade
	EquityFieldRegularMarketLastSize        EquityField = 30 //		integer	 	Currently realize/100, only records regular trade
	EquityFieldRegularMarketNetChange       EquityField = 31 //		double	 	RegularMarketLastPrice - ClosePrice
	EquityFieldSecurityStatus               EquityField = 32 //		String	 	Indicates a symbols current trading status, Normal, Halted, Closed
	EquityFieldMarkPrice                    EquityField = 33 //		double	Mark Price
	EquityFieldQuoteTimeInLong              EquityField = 34 //		Long	Last time a bid or ask updated in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	EquityFieldTradeTimeInLong              EquityField = 35 //		Long	Last trade time in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	EquityFieldRegularMarketTradeTimeInLong EquityField = 36 //		Long	Regular market trade time in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	EquityFieldBidTime                      EquityField = 37 //		long	Last bid time in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	EquityFieldAskTime                      EquityField = 38 //		long	Last ask time in milliseconds since Epoch	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	EquityFieldAskMicID                     EquityField = 39 //		String	4-chars Market Identifier Code
	EquityFieldBidMicID                     EquityField = 40 //		String	4-chars Market Identifier Code
	EquityFieldLastMicID                    EquityField = 41 //		String	4-chars Market Identifier Code
	EquityFieldNetPercentChange             EquityField = 42 //		double	Net Percentage Change	NetChange / ClosePrice * 100
	EquityFieldRegularMarketPercentChange   EquityField = 43 //		double	Regular market hours percentage change	RegularMarketNetChange / ClosePrice * 100
	EquityFieldMarkPriceNetChange           EquityField = 44 //		double	Mark price net change	7.97
	EquityFieldMarkPricePercentChange       EquityField = 45 //		double	Mark price percentage change	4.2358
	EquityFieldHardtoBorrowQuantity         EquityField = 46 //		integer	 	-1 = NULL   >=0 is valid quantity
	EquityFieldHardToBorrowRate             EquityField = 47 //		double	 	null = NULL   valid range = -99,999.999 to +99,999.999
	EquityFieldHardtoBorrow                 EquityField = 48 //		integer	 	-1 = NULL 1 = true 0 = false
	EquityFieldShortable                    EquityField = 49 //		integer	 	-1 = NULL  1 = true 0 = false
	EquityFieldPostMarketNetChange          EquityField = 50 //		double	Change in price since the end of the regular session (typically 4:00pm)	PostMarketLastPrice - RegularMarketLastPrice
	EquityFieldPostMarketPercentChange      EquityField = 51 //		double	Percent Change in price since the end of the regular session (typically 4:00pm)	PostMarketNetChange / RegularMarketLastPrice * 100
)

func EquityFieldString

func EquityFieldString(s string) (EquityField, error)

EquityFieldString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func EquityFieldValues

func EquityFieldValues() []EquityField

EquityFieldValues returns all values of the enum

func (EquityField) IsAEquityField

func (i EquityField) IsAEquityField() bool

IsAEquityField returns "true" if the value is listed in the enum definition. "false" otherwise

func (EquityField) String

func (i EquityField) String() string

type EquityReq

type EquityReq struct {
	Symbols []string
	Fields  []EquityField
}

func (*EquityReq) MarshalJSON

func (e *EquityReq) MarshalJSON() ([]byte, error)

type ExchangeID

type ExchangeID byte
const (
	ExchangeIDUnspecified ExchangeID = iota
	ExchangeIDAmex
	ExchangeIDIndicator
	ExchangeIDIndices
	ExchangeIDMutualFund
	ExchangeIDNasdaq
	ExchangeIDNyse
	ExchangeIDPacific
	ExchangeIDPinks
	ExchangeIDOtcbb
)

func ExchangeIDString

func ExchangeIDString(s string) (ExchangeID, error)

ExchangeIDString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func ExchangeIDValues

func ExchangeIDValues() []ExchangeID

ExchangeIDValues returns all values of the enum

func (ExchangeID) IsAExchangeID

func (i ExchangeID) IsAExchangeID() bool

IsAExchangeID returns "true" if the value is listed in the enum definition. "false" otherwise

func (ExchangeID) String

func (i ExchangeID) String() string

func (*ExchangeID) UnmarshalJSON

func (e *ExchangeID) UnmarshalJSON(b []byte) error

type FrequencyType

type FrequencyType byte
const (
	FrequencyTypeUnspecified FrequencyType = iota
	FrequencyTypeMinute
	FrequencyTypeDaily
	FrequencyTypeWeekly
	FrequencyTypeMonthly
)

func FrequencyTypeString

func FrequencyTypeString(s string) (FrequencyType, error)

FrequencyTypeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func FrequencyTypeValues

func FrequencyTypeValues() []FrequencyType

FrequencyTypeValues returns all values of the enum

func (FrequencyType) IsAFrequencyType

func (i FrequencyType) IsAFrequencyType() bool

IsAFrequencyType returns "true" if the value is listed in the enum definition. "false" otherwise

func (FrequencyType) MarshalJSON

func (i FrequencyType) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for FrequencyType

func (FrequencyType) String

func (i FrequencyType) String() string

func (*FrequencyType) UnmarshalJSON

func (i *FrequencyType) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for FrequencyType

type Future

type Future struct {
	Symbol      FutureID   `json:"0"`  // Ticker symbol in upper case
	BidPrice    float64    `json:"1"`  // Current Best Bid Price
	AskPrice    float64    `json:"2"`  // Current Best Ask Price
	LastPrice   float64    `json:"3"`  // Price at which the last trade was matched
	BidSize     int64      `json:"4"`  // Number of contracts for bid
	AskSize     int64      `json:"5"`  // Number of contracts for ask
	BidID       ExchangeID `json:"6"`  // Exchange with the best bid
	AskID       ExchangeID `json:"7"`  // Exchange with the best ask
	TotalVolume int64      `json:"8"`  // Aggregated contracts traded throughout the day, including pre/post market hours
	LastSize    int64      `json:"9"`  // Number of contracts traded with last trade
	QuoteTime   time.Time  `json:"10"` // Time of the last quote in milliseconds since epoch
	TradeTime   time.Time  `json:"11"` // Time of the last trade in milliseconds since epoch
	HighPrice   float64    `json:"12"` // Day's high trade price
	LowPrice    float64    `json:"13"` // Day's low trade price
	ClosePrice  float64    `json:"14"` // Previous day's closing price
	ExchangeID  ExchangeID `json:"15"` // Primary "listing" Exchange
	Description string     `json:"16"` // Description of the product
	LastID      ExchangeID `json:"17"` // Exchange where last trade was executed
	OpenPrice   float64    `json:"18"` // Day's Open Price

	// NetChange = (CurrentLast - Prev Close);
	// If(close>0) change = lastclose; else change=0
	NetChange float64 `json:"19"`

	PercentChange  float64        `json:"20"` //	If(close>0) pctChange = (last – close)/close else pctChange=0
	ExchangeName   string         `json:"21"` //	Name of exchange
	SecurityStatus SecurityStatus `json:"22"` //	Trading status of the symbol
	OpenInterest   int            `json:"23"` //	The total number of futures contracts that are not closed or delivered on a particular day

	// Mark-to-Market value is calculated daily using current prices to determine
	// profit/loss		If lastprice is within spread, value = lastprice else
	// value=(bid+ask)/2
	Mark float64 `json:"24"`

	Tick       float64 `json:"25"` //	Minimum price movement	N/A	N/A	Minimum price increment of contract
	TickAmount float64 `json:"26"` //	Minimum amount that the price of the market can change	N/A	N/A	Tick * multiplier field
	Product    string  `json:"27"` //	Futures product

	//	Display in fraction or decimal format. Set from FSP Config
	//
	// format is \< numerator decimals to display\>, \< implied denominator>
	// where D=decimal format, no fractional display
	// Equity futures will be "D,D" to indicate pure decimal.
	// Fixed income futures are fractional, typically "3,32".
	// Below is an example for "3,32":
	// price=101.8203125
	// =101 + 0.8203125 (split into whole and fractional)
	// =101 + 26.25/32 (Multiply fractional by implied denomiator)
	// =101 + 26.2/32 (round to numerator decimals to display)
	// =101'262 (display in fractional format)
	FuturePriceFmt string `json:"28"`

	//	Hours	String	Trading hours	N/A	N/A	days: 0 = monday-friday, 1 = sunday,
	//
	// 7 = Saturday
	// 0 = [-2000,1700] ==> open, close
	// 1= [-1530,-1630,-1700,1515] ==> open, close, open, close
	// 0 = [-1800,1700,d,-1700,1900] ==> open, close, DST-flag, open, close
	TradingHours string `json:"29"`

	IsTradable      bool      `json:"30"` //	Flag to indicate if this future contract is tradable	N/A	N/A
	Multiplier      float64   `json:"31"` //	Point value
	IsActive        bool      `json:"32"` //	Indicates if this contract is active
	SettlementPrice float64   `json:"33"` //	Closing price
	ActiveSymbol    string    `json:"34"` //	Symbol of the active contract
	ExpirationDate  time.Time `json:"35"` //	Expiration date of this contract
	ExpirationStyle string    `json:"36"`
	AskTime         time.Time `json:"37"` //	Time of the last ask-side quote
	BidTime         time.Time `json:"38"` //	Time of the last bid-side quote
	QuotedInSession bool      `json:"39"` //	Indicates if this contract has quoted during the active session
	SettlementDate  time.Time `json:"40"` //	Expiration date of this contract
}

func (*Future) UnmarshalJSON

func (f *Future) UnmarshalJSON(b []byte) error

type FutureField

type FutureField byte
const (
	FutureFieldSymbol FutureField = iota
	FutureFieldBidPrice
	FutureFieldAskPrice
	FutureFieldLastPrice
	FutureFieldBidSize
	FutureFieldAskSize
	FutureFieldBidID
	FutureFieldAskID
	FutureFieldTotalVolume
	FutureFieldLastSize
	FutureFieldQuoteTime
	FutureFieldTradeTime
	FutureFieldHighPrice
	FutureFieldLowPrice
	FutureFieldClosePrice
	FutureFieldExchangeID
	FutureFieldDescription
	FutureFieldLastID
	FutureFieldOpenPrice
	FutureFieldNetChange
	FutureFieldPercentChange
	FutureFieldExchangeName
	FutureFieldSecurityStatus
	FutureFieldOpenInterest
	FutureFieldMark
	FutureFieldTick
	FutureFieldTickAmount
	FutureFieldProduct
	FutureFieldFuturePriceFmt
	FutureFieldTradingHours
	FutureFieldIsTradable
	FutureFieldMultiplier
	FutureFieldIsActive
	FutureFieldSettlementPrice
	FutureFieldActiveSymbol
	FutureFieldExpirationDate
	FutureFieldExpirationStyle
	FutureFieldAskTime
	FutureFieldBidTime
	FutureFieldQuotedInSession
	FutureFieldSettlementDate
)

func FutureFieldString

func FutureFieldString(s string) (FutureField, error)

FutureFieldString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func FutureFieldValues

func FutureFieldValues() []FutureField

FutureFieldValues returns all values of the enum

func (FutureField) IsAFutureField

func (i FutureField) IsAFutureField() bool

IsAFutureField returns "true" if the value is listed in the enum definition. "false" otherwise

func (FutureField) String

func (i FutureField) String() string

type FutureID

type FutureID struct {
	Symbol string
	Month  time.Month
	Year   uint8 // last 2 digits of the year
}

Futures symbols in upper case and separated by commas. Schwab-standard format: '/' + 'root symbol' + 'month code' + 'year code' where month code is:

F: January
G: February
H: March
J: April
K: May
M: June
N: July
Q: August
U: September
V: October
X: November
Z: December

and year code is the last two digits of the year Common roots: ES: E-Mini S&P 500 NQ: E-Mini Nasdaq 100 CL: Light Sweet Crude Oil GC: Gold HO: Heating Oil BZ: Brent Crude Oil YM: Mini Dow Jones Industrial Average

func (*FutureID) MonthCode

func (f *FutureID) MonthCode() rune

func (FutureID) String

func (f FutureID) String() string

func (*FutureID) UnmarshalJSON

func (f *FutureID) UnmarshalJSON(b []byte) error

type FutureOption

type FutureOption struct {
	Symbol                string         `json:"0"`  // Tickersymbol in upper case.
	BidPrice              float64        `json:"1"`  // Current Bid Price
	AskPrice              float64        `json:"2"`  // Current Ask Price
	LastPrice             float64        `json:"3"`  // Price at which the last trade was matched
	BidSize               int64          `json:"4"`  // Number of contracts for bid
	AskSize               int64          `json:"5"`  // Number of contracts for ask
	BidID                 ExchangeID     `json:"6"`  // Exchange with the bid
	AskID                 ExchangeID     `json:"7"`  // Exchange with the ask
	TotalVolume           int64          `json:"8"`  // Aggregated contracts traded throughout the day, including pre/post market hours.
	LastSize              int64          `json:"9"`  // Number of contracts traded with last trade
	QuoteTime             time.Time      `json:"10"` // Trade time of the last quote
	TradeTime             time.Time      `json:"11"` // Trade time of the last trade
	HighPrice             float64        `json:"12"` // Day's high trade price
	LowPrice              float64        `json:"13"` // Day's low trade price
	ClosePrice            float64        `json:"14"` // Previous day's closing price
	LastID                ExchangeID     `json:"15"` // Exchange where last trade was executed
	Description           string         `json:"16"` // Description of the product
	OpenPrice             float64        `json:"17"` // Day's Open Price
	OpenInterest          float64        `json:"18"`
	Mark                  float64        `json:"19"` // Mark-to-Marketvalue is calculated daily using current prices to determine profit/loss		If lastprice is within spread,  value= lastprice else value=(bid+ask)/2
	Tick                  float64        `json:"20"` // Minimumprice movement		Minimum price increment of contract
	TickAmount            float64        `json:"21"` // Minimum amount that the price of the market can change		Tick * multiplier field
	FutureMultiplier      float64        `json:"22"` // Point value
	FutureSettlementPrice float64        `json:"23"` // Closing price
	UnderlyingSymbol      string         `json:"24"` // Underlying symbol
	StrikePrice           float64        `json:"25"` // Strike Price
	FutureExpirationDate  time.Time      `json:"26"` // Expiration date of this contract
	ExpirationStyle       string         `json:"27"`
	Side                  OptionSide     `json:"28"`
	Status                SecurityStatus `json:"29"`
	Exchange              ExchangeID     `json:"30"` // Exchangecharacter
	ExchangeName          string         `json:"31"` // Display name of exchange
}

func (*FutureOption) UnmarshalJSON

func (f *FutureOption) UnmarshalJSON(b []byte) error

type FutureOptionField

type FutureOptionField byte
const (
	FutureOptionFieldSymbol FutureOptionField = iota
	FutureOptionFieldBidPrice
	FutureOptionFieldAskPrice
	FutureOptionFieldLastPrice
	FutureOptionFieldBidSize
	FutureOptionFieldAskSize
	FutureOptionFieldBidID
	FutureOptionFieldAskID
	FutureOptionFieldTotalVolume
	FutureOptionFieldLastSize
	FutureOptionFieldQuoteTime
	FutureOptionFieldTradeTime
	FutureOptionFieldHighPrice
	FutureOptionFieldLowPrice
	FutureOptionFieldClosePrice
	FutureOptionFieldLastID
	FutureOptionFieldDescription
	FutureOptionFieldOpenPrice
	FutureOptionFieldOpenInterest
	FutureOptionFieldMark
	FutureOptionFieldTick
	FutureOptionFieldTickAmount
	FutureOptionFieldFutureMultiplier
	FutureOptionFieldFutureSettlementPrice
	FutureOptionFieldUnderlyingSymbol
	FutureOptionFieldStrikePrice
	FutureOptionFieldFutureExpirationDate
	FutureOptionFieldExpirationStyle
	FutureOptionFieldSide
	FutureOptionFieldStatus
	FutureOptionFieldExchange
	FutureOptionFieldExchangeName
)

func FutureOptionFieldString

func FutureOptionFieldString(s string) (FutureOptionField, error)

FutureOptionFieldString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func FutureOptionFieldValues

func FutureOptionFieldValues() []FutureOptionField

FutureOptionFieldValues returns all values of the enum

func (FutureOptionField) IsAFutureOptionField

func (i FutureOptionField) IsAFutureOptionField() bool

IsAFutureOptionField returns "true" if the value is listed in the enum definition. "false" otherwise

func (FutureOptionField) String

func (i FutureOptionField) String() string

type FutureOptionID

type FutureOptionID struct {
	Symbol string
	Month  time.Month
	Year   uint8
	Side   OptionSide
	Strike float64
}

func (*FutureOptionID) String

func (f *FutureOptionID) String() string

func (*FutureOptionID) UnmarshalJSON

func (f *FutureOptionID) UnmarshalJSON(b []byte) (err error)

type FutureOptionReq

type FutureOptionReq struct {
	Symbols []FutureOptionID
	Fields  []FutureOptionField
}

func (*FutureOptionReq) MarshalJSON

func (f *FutureOptionReq) MarshalJSON() ([]byte, error)

type FutureReq

type FutureReq struct {
	Symbols []FutureID    `json:"keys"`
	Fields  []FutureField `json:"fields"`
}

func (*FutureReq) MarshalJSON

func (f *FutureReq) MarshalJSON() ([]byte, error)

type HTTPClient

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

HTTP client is the client for http requests via schwab. You need it for at least fetching a token. The websocket client is the preferred client method due to better latency all around

func New

func New(baseURL, authURL, key, secret string, opts ...HTTPClientOpt) *HTTPClient

func (*HTTPClient) Authenticate

func (c *HTTPClient) Authenticate(ctx context.Context, refreshToken string) (oauth2.Token, error)

Force authentication to happen. The returned token is a copy of the internal one that will be used for future requests. After calling this function there will be automatic refreshes until eventually the refresh token expires. By this point you will need to follow the flow to get a new one, which is unfortunately a manual process

func (*HTTPClient) GetPreferences

func (s *HTTPClient) GetPreferences(ctx context.Context, accountID string) (*Preferences, error)

GetPreferences returns Preferences for a specific account. See https://developer.tdameritrade.com/user-principal/apis/get/accounts/%7BaccountId%7D/preferences-0

func (*HTTPClient) GetQuotes

func (c *HTTPClient) GetQuotes(ctx context.Context, symbol string) (map[string]Quote, error)

func (*HTTPClient) GetStreamerSubscriptionKeys

func (s *HTTPClient) GetStreamerSubscriptionKeys(ctx context.Context, accountIDs ...string) (*StreamerSubscriptionKeys, error)

GetStreamerSubscriptionKeys returns Subscription Keys for provided accounts or default accounts. See https://developer.tdameritrade.com/user-principal/apis/get/userprincipals/streamersubscriptionkeys-0

func (*HTTPClient) GetUserPreference

func (s *HTTPClient) GetUserPreference(ctx context.Context) (*UserPrincipal, error)

GetUserPreference returns User Preference details.

func (*HTTPClient) GetUserPrincipals

func (s *HTTPClient) GetUserPrincipals(ctx context.Context, fields ...UserPrincipalField) (*UserPrincipal, error)

GetUserPrincipals returns User Principal details. Valid values for `fields` are "streamerSubscriptionKeys", "streamerConnectionInfo", "preferences" and "surrogateIds" See https://developer.tdameritrade.com/user-principal/apis/get/userprincipals-0

func (*HTTPClient) PriceHistory

func (c *HTTPClient) PriceHistory(ctx context.Context, symbol string, req *PriceHistoryReq) ([]Candle, error)

func (*HTTPClient) UpdatePreferences

func (s *HTTPClient) UpdatePreferences(ctx context.Context, accountID string, newPreferences *Preferences) error

UpdatePreferences updates Preferences for a specific account. Please note that the directOptionsRouting and directEquityRouting values cannot be modified via this operation, even though they are in the request body. See https://developer.tdameritrade.com/user-principal/apis/put/accounts/%7BaccountId%7D/preferences-0

type HTTPClientOpt

type HTTPClientOpt func(c *HTTPClient)

func WithClientLogger

func WithClientLogger(l slog.Handler) HTTPClientOpt

func WithHTTPAccessToken

func WithHTTPAccessToken(s string) HTTPClientOpt

Give an already valid access token to the client to avoid fetching one

type HTTPErr

type HTTPErr struct {
	ID     uuid.UUID `json:"id"`
	Status int       `json:"status"`
	Title  string    `json:"Title"`
}

func (*HTTPErr) Error

func (h *HTTPErr) Error() string

type KeyEntry

type KeyEntry struct {
	Key string `json:"key"`
}

type LoginResp

type LoginResp struct {
	Server string
	ConnStatus
}

type Option

type Option struct {
	Symbol      string  `json:"0"`
	Description string  `json:"1"`
	BidPrice    float64 `json:"2"` //  Current Bid Price
	AskPrice    float64 `json:"3"` //  Current Ask Price
	LastPrice   float64 `json:"4"` //  Price at which the last trade was matched

	// Per industry standard, only regular session trades set the High and Low. If a
	// stock does not trade in the regular session, high and low will be
	// zero.High/low reset to zero at 3:30am ET
	HighPrice float64 `json:"5"`
	LowPrice  float64 `json:"6"`

	ClosePrice   float64 `json:"7"` //  Closing prices are updated from the DB at 7:29AM ET.
	TotalVolume  int     `json:"8"` //  Aggregated contracts traded throughout the day, including pre/post market hours. Volume is set to zero at 3:30am ET.
	OpenInterest int     `json:"9"`
	Volatility   float64 `json:"10"` // Option Risk/Volatility Measurement/Implied. Volatility is reset to 0 at 3:30am ET

	// The value an option would have if it were exercised today. Basically, the
	// intrinsic value is the amount by which the strike price of an option is
	// profitable or in-the-money as compared to the underlying stock's price in the
	// market.	Yes	No	In-the-money is positive, out-of-the money is negative.
	MoneyIntrinsicValue float64 `json:"11"`

	ExpirationYear        int     `json:"12"`
	Multiplier            float64 `json:"13"`
	NumberOfDecimalPlaces int     `json:"14"` // Number of decimal places

	// According to industry standard, only regular session trades set the open If a
	// stock does not trade during the regular session, then the open price is 0. In
	// the pre-market session, open is blank because pre-market session trades do
	// not set the open. Open is set to ZERO at 7:28 ET.
	OpenPrice              float64        `json:"15"`
	BidSize                int            `json:"16"` // Number of contracts for bid
	AskSize                int            `json:"17"` // Number of contracts for ask
	LastSize               int            `json:"18"` // Number of contracts traded with last trade. Size in 100's
	NetChange              float64        `json:"19"` // Current Last-Prev Close. If(close>0) { change = last close } else { change = 0 }
	StrikePrice            float64        `json:"20"`
	ContractType           rune           `json:"21"`
	Underlying             string         `json:"22"`
	ExpirationMonth        int            `json:"23"`
	Deliverables           string         `json:"24"`
	TimeValue              float64        `json:"25"`
	ExpirationDay          int            `json:"26"`
	DaysToExpiration       int            `json:"27"`
	Delta                  float64        `json:"28"`
	Gamma                  float64        `json:"29"`
	Theta                  float64        `json:"30"`
	Vega                   float64        `json:"31"`
	Rho                    float64        `json:"32"`
	Status                 SecurityStatus `json:"33"` // did the tiny hats start losing money and shut it down?
	TheoreticalOptionValue float64        `json:"34"`
	UnderlyingPrice        float64        `json:"35"`
	UVExpirationType       rune           `json:"36"`
	MarkPrice              float64        `json:"37"`
	QuoteTime              time.Time      `json:"38"` // The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	TradeTime              time.Time      `json:"39"` // The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	Exchange               ExchangeID     `json:"40"`
	ExchangeName           string         `json:"41"`
	LastTradingDay         int            `json:"42"`
	SettlementType         rune           `json:"43"`
	NetPercentChange       float64        `json:"44"` // Net Percentage Change	Yes	Yes	4.2358
	MarkPriceNetChange     float64        `json:"45"` // Mark price net change	Yes	Yes	7.97
	MarkPricePercentChange float64        `json:"46"` // Mark price percentage change	Yes	Yes	4.2358
	ImpliedYield           float64        `json:"47"`
	IsPennyPilot           bool           `json:"48"`
	OptionRoot             string         `json:"49"`
	High52Week             float64        `json:"50"`
	Low52Week              float64        `json:"51"`
	IndicativeAskPrice     float64        `json:"52"` // Only valid for index options (0 for all other options)
	IndicativeBidPrice     float64        `json:"53"` // Only valid for index options (0 for all other options)

	// The latest time the indicative bid/ask prices updated in milliseconds since
	// Epoch	 	Only valid for index options (0 for all other options) The
	// difference, measured in milliseconds, between the time an event occurs and
	// midnight, January 1, 1970 UTC.
	IndicativeQuoteTime time.Time `json:"54"`
	ExerciseType        rune      `json:"55"`
}

func (*Option) UnmarshalJSON

func (o *Option) UnmarshalJSON(b []byte) error

type OptionField

type OptionField byte
const (
	OptionFieldSymbol                 OptionField = 0  //		String	Ticker symbol in upper case.	N/A	N/A
	OptionFieldDescription            OptionField = 1  //	String	A company, index or fund name	Yes	Yes	Descriptions are loaded from the database daily at 3:30 am ET.
	OptionFieldBidPrice               OptionField = 2  // double	Current Bid Price	Yes	No
	OptionFieldAskPrice               OptionField = 3  // double	Current Ask Price	Yes	No
	OptionFieldLastPrice              OptionField = 4  //	double	Price at which the last trade was matched	Yes	No
	OptionFieldHighPrice              OptionField = 5  //	double	Day's high trade price	Yes	No	According to industry standard, only regular session trades set the High and Low. If a stock does not trade in the regular session, high and low will be zero.High/low reset to zero at 3:30am ET
	OptionFieldLowPrice               OptionField = 6  //	double	Day's low trade price	Yes	No	See High Price notes
	OptionFieldClosePrice             OptionField = 7  //	double	Previous day's closing price	No	No	Closing prices are updated from the DB at 7:29AM ET.
	OptionFieldTotalVolume            OptionField = 8  //	long	Aggregated contracts traded throughout the day, including pre/post market hours.	Yes	No	Volume is set to zero at 3:30am ET.
	OptionFieldOpenInterest           OptionField = 9  //	int	 	Yes	No
	OptionFieldVolatility             OptionField = 10 //	double	Option Risk/Volatility Measurement/Implied	Yes	No	Volatility is reset to 0 at 3:30am ET
	OptionFieldMoneyIntrinsicValue    OptionField = 11 //	double	The value an option would have if it were exercised today. Basically, the intrinsic value is the amount by which the strike price of an option is profitable or in-the-money as compared to the underlying stock's price in the market.	Yes	No	In-the-money is positive, out-of-the money is negative.
	OptionFieldExpirationYear         OptionField = 12 //	int
	OptionFieldMultiplier             OptionField = 13 //	double
	OptionFieldDigits                 OptionField = 14 //	int	Number of decimal places
	OptionFieldOpenPrice              OptionField = 15 //	double	Day's Open Price Yes No According to industry standard, only regular session trades set the open If a stock does not trade during the regular session, then the open price is 0. In the pre-market session, open is blank because pre-market session trades do not set the open. Open is set to ZERO at 7:28 ET.
	OptionFieldBidSize                OptionField = 16 //	int	Number of contracts for bid	Yes	No	From FH
	OptionFieldAskSize                OptionField = 17 //	int	Number of contracts for ask	Yes	No	From FH
	OptionFieldLastSize               OptionField = 18 //	int	Number of contracts traded with last trade	Yes	No	Size in 100's
	OptionFieldNetChange              OptionField = 19 //	double	Current Last-Prev Close	Yes	No	If(close>0)  change = last – close Else change=0
	OptionFieldStrikePrice            OptionField = 20 //	double	Contract strike price	Yes	No
	OptionFieldContractType           OptionField = 21 //	char
	OptionFieldUnderlying             OptionField = 22 //	String
	OptionFieldExpirationMonth        OptionField = 23 //	int
	OptionFieldDeliverables           OptionField = 24 //	String
	OptionFieldTimeValue              OptionField = 25 //	double
	OptionFieldExpirationDay          OptionField = 26 //	int
	OptionFieldDaysToExpiration       OptionField = 27 // int
	OptionFieldDelta                  OptionField = 28 //	double
	OptionFieldGamma                  OptionField = 29 //	double
	OptionFieldTheta                  OptionField = 30 //	double
	OptionFieldVega                   OptionField = 31 //	double
	OptionFieldRho                    OptionField = 32 //	double
	OptionFieldSecurityStatus         OptionField = 33 //	String	 	Yes	Yes	Indicates a symbol's current trading status: Normal, Halted, Closed
	OptionFieldTheoreticalOptionValue OptionField = 34 // double
	OptionFieldUnderlyingPrice        OptionField = 35 //	double
	OptionFieldUVExpirationType       OptionField = 36 // char
	OptionFieldMarkPrice              OptionField = 37 //	double	Mark Price	Yes	Yes
	OptionFieldQuoteTime              OptionField = 38 // in Long	long	Last quote time in milliseconds since Epoch	Yes	Yes The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	OptionFieldTradeTime              OptionField = 39 // in Long	long	Last trade time in milliseconds since Epoch	Yes	Yes	The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	OptionFieldExchange               OptionField = 40 //	char	Exchangecharacter	Yes	Yes	o
	OptionFieldExchangeName           OptionField = 41 //	String	Display name of exchange	Yes	Yes
	OptionFieldLastTradingDay         OptionField = 42 // Day	long	Last Trading Day	Yes	Yes
	OptionFieldSettlementType         OptionField = 43 //	char	Settlement type character	Yes	Yes
	OptionFieldNetPercentChange       OptionField = 44 // double	Net Percentage Change	Yes	Yes	4.2358
	OptionFieldMarkPriceNetChange     OptionField = 45 // double	Mark price net change	Yes	Yes	7.97
	OptionFieldMarkPricePercentChange OptionField = 46 // double	Mark price percentage change	Yes	Yes	4.2358
	OptionFieldImpliedYield           OptionField = 47 //	double
	OptionFieldisPennyPilot           OptionField = 48 //	boolean
	OptionFieldOptionRoot             OptionField = 49 //	String
	OptionField52WeekHigh             OptionField = 50 //double
	OptionField52WeekLow              OptionField = 51 // double
	OptionFieldIndicativeAskPrice     OptionField = 52 //	double	 	 	 	Only valid for index options (0 for all other options)
	OptionFieldIndicativeBidPrice     OptionField = 53 //	double	 	 	 	Only valid for index options (0 for all other options)
	OptionFieldIndicativeQuoteTime    OptionField = 54 //	long	The latest time the indicative bid/ask prices updated in milliseconds since Epoch	 	Only valid for index options (0 for all other options) The difference, measured in milliseconds, between the time an event occurs and midnight, January 1, 1970 UTC.
	OptionFieldExerciseType           OptionField = 55 // char
)

func OptionFieldString

func OptionFieldString(s string) (OptionField, error)

OptionFieldString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func OptionFieldValues

func OptionFieldValues() []OptionField

OptionFieldValues returns all values of the enum

func (OptionField) IsAOptionField

func (i OptionField) IsAOptionField() bool

IsAOptionField returns "true" if the value is listed in the enum definition. "false" otherwise

func (OptionField) String

func (i OptionField) String() string

type OptionID

type OptionID struct {
	Symbol     string
	Expiration time.Time
	Side       OptionSide
	Strike     float64
}

func (*OptionID) MarshalJSON

func (o *OptionID) MarshalJSON() ([]byte, error)

func (*OptionID) String

func (o *OptionID) String() string

Options symbols in uppercase and separated by commas Schwab-standard option symbol format: RRRRRRYYMMDDsWWWWWddd Where:

R is the space-filled root
symbol YY is the expiration year
MM is the expiration month
DD is the expiration day
s is the side: C/P (call/put)
WWWWW is the whole portion of the strike price
nnn is the decimal portion of the strike price

e.g.: AAPL 251219C00200000

func (*OptionID) UnmarshalJSON

func (o *OptionID) UnmarshalJSON(b []byte) error

func (*OptionID) UnmarshalText

func (o *OptionID) UnmarshalText(s string) (err error)

func (*OptionID) Validate

func (o *OptionID) Validate() error

type OptionReq

type OptionReq struct {
	Options []OptionID
	Fields  []OptionField
}

func (*OptionReq) MarshalJSON

func (o *OptionReq) MarshalJSON() ([]byte, error)

type OptionSide

type OptionSide byte
const (
	OptionSideUnspecified OptionSide = iota
	OptionSideCall
	OptionSidePut
)

func (OptionSide) MarshalJSON

func (o OptionSide) MarshalJSON() ([]byte, error)

func (OptionSide) String

func (o OptionSide) String() string

func (*OptionSide) UnmarshalJSON

func (o *OptionSide) UnmarshalJSON(b []byte) error

func (*OptionSide) UnmarshalText

func (o *OptionSide) UnmarshalText(s string) error

type PeriodType

type PeriodType byte
const (
	HistoryPeriodUnspecified PeriodType = iota
	HistoryPeriodDay
	HistoryPeriodMonth
	HistoryPeriodYear
	HistoryPeriodYTD
)

func PeriodTypeString

func PeriodTypeString(s string) (PeriodType, error)

PeriodTypeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func PeriodTypeValues

func PeriodTypeValues() []PeriodType

PeriodTypeValues returns all values of the enum

func (PeriodType) IsAPeriodType

func (i PeriodType) IsAPeriodType() bool

IsAPeriodType returns "true" if the value is listed in the enum definition. "false" otherwise

func (PeriodType) MarshalJSON

func (i PeriodType) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for PeriodType

func (PeriodType) String

func (i PeriodType) String() string

func (*PeriodType) UnmarshalJSON

func (i *PeriodType) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for PeriodType

type Preferences

type Preferences struct {
	ExpressTrading                   bool   `json:"expressTrading"`
	DirectOptionsRouting             bool   `json:"directOptionsRouting"`
	DirectEquityRouting              bool   `json:"directEquityRouting"`
	DefaultEquityOrderLegInstruction string `json:"defaultEquityOrderLegInstruction"`
	DefaultEquityOrderType           string `json:"defaultEquityOrderType"`
	DefaultEquityOrderPriceLinkType  string `json:"defaultEquityOrderPriceLinkType"`
	DefaultEquityOrderDuration       string `json:"defaultEquityOrderDuration"`
	DefaultEquityOrderMarketSession  string `json:"defaultEquityOrderMarketSession"`
	DefaultEquityQuantity            int    `json:"defaultEquityQuantity"`
	MutualFundTaxLotMethod           string `json:"mutualFundTaxLotMethod"`
	OptionTaxLotMethod               string `json:"optionTaxLotMethod"`
	EquityTaxLotMethod               string `json:"equityTaxLotMethod"`
	DefaultAdvancedToolLaunch        string `json:"defaultAdvancedToolLaunch"`
	AuthTokenTimeout                 string `json:"authTokenTimeout"`
}

type PriceHistoryReq

type PriceHistoryReq struct {
	// Set this or start/end
	Period     int
	PeriodType PeriodType

	Frequency     int
	FrequencyType FrequencyType

	// Set these or period
	Start, End            time.Time
	NeedExtendedHoursData bool
}

func (*PriceHistoryReq) MarshalJSON

func (p *PriceHistoryReq) MarshalJSON() ([]byte, error)

type Quote

type Quote struct {
	AssetType                          string  `json:"assetType"`
	AssetMainType                      string  `json:"assetMainType"`
	Cusip                              string  `json:"cusip"`
	AssetSubType                       string  `json:"assetSubType"`
	Symbol                             string  `json:"symbol"`
	Description                        string  `json:"description"`
	BidPrice                           float64 `json:"bidPrice"`
	BidSize                            float64 `json:"bidSize"`
	BidID                              string  `json:"bidId"`
	AskPrice                           float64 `json:"askPrice"`
	AskSize                            float64 `json:"askSize"`
	AskID                              string  `json:"askId"`
	LastPrice                          float64 `json:"lastPrice"`
	LastSize                           float64 `json:"lastSize"`
	LastID                             string  `json:"lastId"`
	OpenPrice                          float64 `json:"openPrice"`
	HighPrice                          float64 `json:"highPrice"`
	LowPrice                           float64 `json:"lowPrice"`
	BidTick                            string  `json:"bidTick"`
	ClosePrice                         float64 `json:"closePrice"`
	NetChange                          float64 `json:"netChange"`
	TotalVolume                        float64 `json:"totalVolume"`
	QuoteTimeInLong                    int64   `json:"quoteTimeInLong"`
	TradeTimeInLong                    int64   `json:"tradeTimeInLong"`
	Mark                               float64 `json:"mark"`
	Exchange                           string  `json:"exchange"`
	ExchangeName                       string  `json:"exchangeName"`
	Marginable                         bool    `json:"marginable"`
	Shortable                          bool    `json:"shortable"`
	Volatility                         float64 `json:"volatility"`
	Digits                             int     `json:"digits"`
	Five2WkHigh                        float64 `json:"52WkHigh"`
	Five2WkLow                         float64 `json:"52WkLow"`
	NAV                                float64 `json:"nAV"`
	PeRatio                            float64 `json:"peRatio"`
	DivAmount                          float64 `json:"divAmount"`
	DivYield                           float64 `json:"divYield"`
	DivDate                            string  `json:"divDate"`
	SecurityStatus                     string  `json:"securityStatus"`
	RegularMarketLastPrice             float64 `json:"regularMarketLastPrice"`
	RegularMarketLastSize              int     `json:"regularMarketLastSize"`
	RegularMarketNetChange             float64 `json:"regularMarketNetChange"`
	RegularMarketTradeTimeInLong       int64   `json:"regularMarketTradeTimeInLong"`
	NetPercentChangeInDouble           float64 `json:"netPercentChangeInDouble"`
	MarkChangeInDouble                 float64 `json:"markChangeInDouble"`
	MarkPercentChangeInDouble          float64 `json:"markPercentChangeInDouble"`
	RegularMarketPercentChangeInDouble float64 `json:"regularMarketPercentChangeInDouble"`
	Delayed                            bool    `json:"delayed"`
}

type QuoteDelays

type QuoteDelays struct {
	IsNyseDelayed   bool `json:"isNyseDelayed"`
	IsNasdaqDelayed bool `json:"isNasdaqDelayed"`
	IsOpraDelayed   bool `json:"isOpraDelayed"`
	IsAmexDelayed   bool `json:"isAmexDelayed"`
	IsCmeDelayed    bool `json:"isCmeDelayed"`
	IsIceDelayed    bool `json:"isIceDelayed"`
	IsForexDelayed  bool `json:"isForexDelayed"`
}

type SecurityStatus

type SecurityStatus byte
const (
	SecurityStatusUnspecified SecurityStatus = iota
	SecurityStatusNormal
	SecurityStatusHalted
	SecurityStatusClosed
)

func SecurityStatusString

func SecurityStatusString(s string) (SecurityStatus, error)

SecurityStatusString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func SecurityStatusValues

func SecurityStatusValues() []SecurityStatus

SecurityStatusValues returns all values of the enum

func (SecurityStatus) IsASecurityStatus

func (i SecurityStatus) IsASecurityStatus() bool

IsASecurityStatus returns "true" if the value is listed in the enum definition. "false" otherwise

func (SecurityStatus) MarshalJSON

func (i SecurityStatus) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for SecurityStatus

func (SecurityStatus) String

func (i SecurityStatus) String() string

func (*SecurityStatus) UnmarshalJSON

func (i *SecurityStatus) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for SecurityStatus

type StreamerInfo

type StreamerInfo struct {
	StreamerSocketURL      string    `json:"streamerSocketUrl"`
	SchwabClientCustomerId string    `json:"schwabClientCustomerId"`
	SchwabClientCorrelId   uuid.UUID `json:"schwabClientCorrelId"`
	SchwabClientChannel    string    `json:"schwabClientChannel"`
	SchwabClientFunctionId string    `json:"schwabClientFunctionId"`
}

type StreamerSubscriptionKeys

type StreamerSubscriptionKeys struct {
	Keys []KeyEntry `json:"keys"`
}

type UserAccountInfo

type UserAccountInfo struct {
	AccountID         string         `json:"accountId"`
	Description       string         `json:"description"`
	DisplayName       string         `json:"displayName"`
	AccountCdDomainID string         `json:"accountCdDomainId"`
	Company           string         `json:"company"`
	Segment           string         `json:"segment"`
	SurrogateIds      string         `json:"surrogateIds"`
	Preferences       Preferences    `json:"preferences"`
	ACL               string         `json:"acl"`
	Authorizations    Authorizations `json:"authorizations"`
}

type UserPrincipal

type UserPrincipal struct {
	AuthToken                string                   `json:"authToken"`
	UserID                   string                   `json:"userId"`
	UserCdDomainID           string                   `json:"userCdDomainId"`
	PrimaryAccountID         string                   `json:"primaryAccountId"`
	LastLoginTime            string                   `json:"lastLoginTime"`
	TokenExpirationTime      string                   `json:"tokenExpirationTime"`
	LoginTime                string                   `json:"loginTime"`
	AccessLevel              string                   `json:"accessLevel"`
	StalePassword            bool                     `json:"stalePassword"`
	StreamerInfo             []StreamerInfo           `json:"streamerInfo"`
	ProfessionalStatus       string                   `json:"professionalStatus"`
	Quotes                   QuoteDelays              `json:"quotes"`
	StreamerSubscriptionKeys StreamerSubscriptionKeys `json:"streamerSubscriptionKeys"`
	Accounts                 []UserAccountInfo        `json:"accounts"`
}

type UserPrincipalField

type UserPrincipalField byte
const (
	UserPrincipalFieldUnspecified UserPrincipalField = iota
	UserPrincipalFieldStreamerSubscriptionKeys
	UserPrincipalFieldStreamerConnectionInfo
	UserPrincipalFieldPreferences
	UserPrincipalFieldSurrogateIds
)

func UserPrincipalFieldString

func UserPrincipalFieldString(s string) (UserPrincipalField, error)

UserPrincipalFieldString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func UserPrincipalFieldValues

func UserPrincipalFieldValues() []UserPrincipalField

UserPrincipalFieldValues returns all values of the enum

func (UserPrincipalField) IsAUserPrincipalField

func (i UserPrincipalField) IsAUserPrincipalField() bool

IsAUserPrincipalField returns "true" if the value is listed in the enum definition. "false" otherwise

func (UserPrincipalField) String

func (i UserPrincipalField) String() string

type WS

type WS struct {
	ConnStatus ConnStatus
	Server     string
	// contains filtered or unexported fields
}

WS provides real time updates from TD Ameritrade's streaming API. See https://developer.tdameritrade.com/content/streaming-data for more information.

func NewSocket

func NewSocket(ctx context.Context, opts *websocket.DialOptions, h *HTTPClient, refreshToken string, wsOpts ...WSOpt) (*WS, error)

func (*WS) AddChartEquitySubscription

func (s *WS) AddChartEquitySubscription(ctx context.Context, subs *ChartEquityReq) (*WSResp, error)

This uses the ADD command to add additional symbols to the subscription list, if any exist. If none exist, then this will create them. If you are creating subscriptions for the first time, you will need to provide a value for subs.Fields, otherwise it's not required

func (*WS) AddChartFutureSubscription

func (s *WS) AddChartFutureSubscription(ctx context.Context, subs *ChartFutureReq) (*WSResp, error)

This uses the ADD command to add additional symbols to the subscription list, if any exist. If none exist, then this will create them. If you are creating subscriptions for the first time, you will need to provide a value for subs.Fields, otherwise it's not required

func (*WS) AddEquitySubscription

func (s *WS) AddEquitySubscription(ctx context.Context, subs *EquityReq) (*WSResp, error)

This uses the ADD command to add additional symbols to the subscription list, if any exist. If none exist, then this will create them. If you are creating subscriptions for the first time, you will need to provide a value for subs.Fields, otherwise it's not required

func (*WS) AddFutureOptionSubscription

func (s *WS) AddFutureOptionSubscription(ctx context.Context, subs *FutureOptionReq) (*WSResp, error)

This uses the ADD command to add additional symbols to the subscription list, if any exist. If none exist, then this will create them. If you are creating subscriptions for the first time, you will need to provide a value for subs.Fields, otherwise it's not required

func (*WS) AddFutureSubscription

func (s *WS) AddFutureSubscription(ctx context.Context, subs *FutureReq) (*WSResp, error)

This uses the ADD command to add additional symbols to the subscription list, if any exist. If none exist, then this will create them. If you are creating subscriptions for the first time, you will need to provide a value for subs.Fields, otherwise it's not required

func (*WS) AddOptionSubscription

func (s *WS) AddOptionSubscription(ctx context.Context, subs *OptionReq) (*WSResp, error)

This uses the ADD command to add additional symbols to the subscription list, if any exist. If none exist, then this will create them. If you are creating subscriptions for the first time, you will need to provide a value for subs.Fields, otherwise it's not required

func (*WS) Close

func (s *WS) Close(ctx context.Context) error

Close will attempt a logout, and finally close the websocket connection regardless if the logout succeeded

func (*WS) SetChartEquitySubscription

func (s *WS) SetChartEquitySubscription(ctx context.Context, subs *ChartEquityReq) (*WSResp, error)

This uses the SUBS command to subscribe. Using this command, you reset your subscriptions to include only this set of symbols and fields

func (*WS) SetChartEquitySubscriptionView

func (s *WS) SetChartEquitySubscriptionView(ctx context.Context, fields ...ChartEquityField) (*WSResp, error)

func (*WS) SetChartFutureSubscription

func (s *WS) SetChartFutureSubscription(ctx context.Context, subs *ChartFutureReq) (*WSResp, error)

This uses the SUBS command to subscribe. Using this command, you reset your subscriptions to include only this set of symbols and fields

func (*WS) SetChartFutureSubscriptionView

func (s *WS) SetChartFutureSubscriptionView(ctx context.Context, fields ...ChartFutureField) (*WSResp, error)

func (*WS) SetEquitySubscription

func (s *WS) SetEquitySubscription(ctx context.Context, subs *EquityReq) (*WSResp, error)

This uses the SUBS command to subscribe to equities. Using this command, you reset your subscriptions to include only this set of symbols and fields

func (*WS) SetEquitySubscriptionView

func (s *WS) SetEquitySubscriptionView(ctx context.Context, fields ...EquityField) (*WSResp, error)

func (*WS) SetFutureOptionSubscription

func (s *WS) SetFutureOptionSubscription(ctx context.Context, subs *FutureOptionReq) (*WSResp, error)

This uses the SUBS command to subscribe. Using this command, you reset your subscriptions to include only this set of symbols and fields

func (*WS) SetFutureOptionSubscriptionView

func (s *WS) SetFutureOptionSubscriptionView(ctx context.Context, fields ...FutureOptionField) (*WSResp, error)

func (*WS) SetFutureSubscription

func (s *WS) SetFutureSubscription(ctx context.Context, subs *FutureReq) (*WSResp, error)

This uses the SUBS command to subscribe. Using this command, you reset your subscriptions to include only this set of symbols and fields

func (*WS) SetFutureSubscriptionView

func (s *WS) SetFutureSubscriptionView(ctx context.Context, fields ...FutureField) (*WSResp, error)

func (*WS) SetOptionSubscription

func (s *WS) SetOptionSubscription(ctx context.Context, subs *OptionReq) (*WSResp, error)

This uses the SUBS command to subscribe to equities. Using this command, you reset your subscriptions to include only this set of symbols and fields

func (*WS) SetOptionSubscriptionView

func (s *WS) SetOptionSubscriptionView(ctx context.Context, fields ...OptionField) (*WSResp, error)

func (*WS) UnsubChartEquitySubscription

func (s *WS) UnsubChartEquitySubscription(ctx context.Context, symbols ...string) (*WSResp, error)

func (*WS) UnsubChartFutureSubscription

func (s *WS) UnsubChartFutureSubscription(ctx context.Context, symbols ...string) (*WSResp, error)

func (*WS) UnsubEquitySubscription

func (s *WS) UnsubEquitySubscription(ctx context.Context, symbols ...string) (*WSResp, error)

func (*WS) UnsubFutureOptionSubscription

func (s *WS) UnsubFutureOptionSubscription(ctx context.Context, symbols ...FutureOptionID) (*WSResp, error)

func (*WS) UnsubFutureSubscription

func (s *WS) UnsubFutureSubscription(ctx context.Context, symbols ...FutureID) (*WSResp, error)

func (*WS) UnsubOptionSubscription

func (s *WS) UnsubOptionSubscription(ctx context.Context, ids ...OptionID) (*WSResp, error)

type WSOpt

type WSOpt func(w *WS)

func WithChartEquityHandler

func WithChartEquityHandler(fn func(*ChartEquity)) WSOpt

Handler that will pass chart equity data back to this function in a goroutine for processing

func WithChartFutureHandler

func WithChartFutureHandler(fn func(*ChartFuture)) WSOpt

Handler that will pass chart futures data back to this function in a goroutine for processing

func WithEquityHandler

func WithEquityHandler(fn func(*Equity)) WSOpt

Handler that will pass equity data back to this function in a goroutine for processing

func WithErrHandler

func WithErrHandler(x func(error)) WSOpt

Anytime there is an error in the keepalive goroutine, the function passed in here will be called if you want to do something custom. By default, when errors are received, they will just be logged

func WithFutureHandler

func WithFutureHandler(fn func(*Future)) WSOpt

Handler that will pass future data back to this function in a goroutine for processing

func WithFutureOptionHandler

func WithFutureOptionHandler(fn func(*FutureOption)) WSOpt

Handler that will pass futures option data back to this function in a goroutine for processing

func WithLogger

func WithLogger(l slog.Handler) WSOpt

func WithOptionHandler

func WithOptionHandler(fn func(*Option)) WSOpt

Handler that will pass option data back to this function in a goroutine for processing

func WithPongHandler

func WithPongHandler(fn func(time.Time)) WSOpt

Every time the server returns a pong, you can choose to handle it. By default, this is a no-op

func WithTimeout

func WithTimeout(t time.Duration) WSOpt

Enforce a per-request timeout different than the default, which is DefaultWSTimeout

type WSResp

type WSResp struct {
	Code WSRespCode `json:"code"`
	Msg  string     `json:"msg"`
}

General response message that usually denotes errors in requests

func (*WSResp) Error

func (w *WSResp) Error() string

type WSRespCode

type WSRespCode uint8
const (
	// The request was successful
	WSRespCodeSuccess WSRespCode = 0

	// The user login has been denied
	// Connection severed? Yes
	WSRespCodeLoginDenied WSRespCode = 3

	// Error of last-resort when no specific error was caught
	// Connection severed? Unknown
	// Should be investigated by Trader API team. Contact TraderAPI@Schwab.com if you see this with the `schwabClientCorrelId` of subscription.
	WSRespCodeUnknownFailure WSRespCode = 9

	// The service is not available
	// Connection severed? No
	// Should be investigated by Trader API team. Please contact TraderAPI@Schwab.com if you see this with the `schwabClientCorrelId` of subscription. Either client is requesting an unsupported service or the service is not running from the source.
	WSRespCodeServiceNotAvailable WSRespCode = 11

	// You've reached the maximum number of connections allowed.
	// Connection severed after error? Yes
	// Client to determine if max connections are expected and proper response to customer. A limit of 1 Streamer connection at any given time from a given user is available.
	WSRespCodeCloseConnection WSRespCode = 12

	// Subscribe or Add command has reached a total subscription symbol limit
	// Connection severed? No
	// Client to determine if symbol limit is expected and proper response to customer.
	WSRespCodeReachedSymbolLimit WSRespCode = 19
	// No connection found for user or new session but no login request	TBD
	// Server cannot find the connection based on the provided SchwabClientCustomerId & SchwabClientCorrelId in the request.Should be investigated by Trader API team. Please contact TraderAPI@Schwab.com if you see this with the `schwabClientCorrelId` of subscription.
	// Common causes:
	//
	// Client does not wait for a successful LOGIN response and issues a command immediately after the LOGIN command. There could be a race condition where the SUB is processed before the LOGIN.
	// Client modifies SchwabClientCustomerId or SchwabClientCorrelId after logging in.
	// Streamer has disconnected the client while processing the command.
	WSRespCodeStreamConnNotFound WSRespCode = 20

	// Command fails to match specification. SDK error or client request error in payload
	// Connection severed? No
	WSRespCodeBadCommandFormat WSRespCode = 21

	// Subscribe command could not be completed successfully
	// Connection severed? No
	// Should be investigated by Trader API team. Please contact TraderAPI@Schwab.com if you see this with the `schwabClientCorrelId` of subscription.
	// Common causes:
	//
	//	Two or more commands are processed in parallel causing one to fail.
	WSRespCodeFailedCommandSubs   WSRespCode = 22
	WSRespCodeFailedCommandUnsubs WSRespCode = 23
	WSRespCodeFailedCommandAdd    WSRespCode = 24
	WSRespCodeFailedCommandView   WSRespCode = 25

	WSRespCodeSucceededCommandSubs   WSRespCode = 26
	WSRespCodeSucceededCommandUnsubs WSRespCode = 27
	WSRespCodeSucceededCommandAdd    WSRespCode = 28
	WSRespCodeSucceededCommandView   WSRespCode = 29

	// Signal that streaming has been terminated due to administrator action, inactivity, or slowness
	WSRespCodeStopStreaming WSRespCode = 30

	WSRespCodeUnknown WSRespCode = math.MaxUint8
)

func WSRespCodeString

func WSRespCodeString(s string) (WSRespCode, error)

WSRespCodeString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func WSRespCodeValues

func WSRespCodeValues() []WSRespCode

WSRespCodeValues returns all values of the enum

func (WSRespCode) IsAWSRespCode

func (i WSRespCode) IsAWSRespCode() bool

IsAWSRespCode returns "true" if the value is listed in the enum definition. "false" otherwise

func (*WSRespCode) MarshalJSON

func (w *WSRespCode) MarshalJSON() ([]byte, error)

func (WSRespCode) String

func (i WSRespCode) String() string

func (*WSRespCode) UnmarshalJSON

func (w *WSRespCode) UnmarshalJSON(b []byte) error

Jump to

Keyboard shortcuts

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