thaler

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: MIT Imports: 17 Imported by: 0

README

thaler-go

The Thaler API from Go: financial data from SEC filings, with the source filing for every value.

go get github.com/thaler-sh/thaler-go
package main

import (
	"context"
	"fmt"
	"log"

	thaler "github.com/thaler-sh/thaler-go"
)

func main() {
	client, err := thaler.New() // THALER_API_KEY; or thaler.WithAPIKey("thaler_…")
	if err != nil {
		log.Fatal(err)
	}
	rows, err := client.Metrics(context.Background(), "AAPL", &thaler.MetricsParams{
		Period: thaler.MetricPeriodAnnual,
		Keys:   []string{"revenue", "net_income"},
	})
	if err != nil {
		log.Fatal(err)
	}
	for _, row := range rows.Data {
		source := ""
		if row.ReadFrom != nil {
			source = row.ReadFrom.AccessionNumber
		}
		fmt.Println(row.EndDate, row.MetricKey, row.Value, source)
	}
	// 2025-09-27 revenue 416161000000 0000320193-25-000079
}

Every figure is a Decimal (the digits as filed; a float loses digits past the fifteenth), every day a Date, every instant a time.Time, and every answer a Response with the request ID and the account’s limits beside its Data. Create a key at thaler.sh/developers/keys.

What the client does

At most four requests are in flight at once. When the minute’s sixty are spent, the next request waits for the reset. A 429 is retried after its Retry-After; one longer than a minute, the month’s limit, is returned as an error at once. A context that ends stops everything at once.

A 500, 502, 503 or 504, or a connection that failed, is retried twice after a growing pause; those answers don’t count against the month. A 400, 401 or 404 is returned as it stands, and a Screener clause the API would refuse is an error before anything is sent.

Figures are Decimal (the digits as filed), days are Date, instants are time.Time, each documented set of values is a string type with a constant per value (a value a later API adds still reads), and a pointer marks what can be absent or null. An answer that is not as documented is a *DecodeError naming the field.

ScreenAll, HoldersAll, HolderPositionsAll and InsiderFilingsAll are iter.Seq2 sequences over every row.

*APIError carries the problem’s Code, Detail and RequestID and a Kind() (ErrorNotFound, ErrorAuthentication, ErrorBadRequest, ErrorRateLimited, ErrorServer); *TransportError wraps its cause; *DecodeError names its field. All read with errors.As.

No dependencies beyond the standard library. Go 1.23 or later.

The client

client, err := thaler.New(
	thaler.WithAPIKey("thaler_…"),               // or THALER_API_KEY
	thaler.WithTimeout(30*time.Second),          // to wait for an answer
	thaler.WithMaxRetries(2),                    // tries after the first, on 429, 5xx or a lost connection
	thaler.WithMaxConcurrent(4),                 // requests in flight; the API allows four
	thaler.WithMaxRetryAfter(60*time.Second),    // the longest Retry-After waited for
)

One client serves a whole program: it is safe for concurrent use, and it is what keeps the account inside its limits. WithHTTPClient sends through an http.Client of your own, for a proxy or a custom transport.

Every call

Each method takes a context, the path’s parts, and a pointer to its parameters (nil for none).

Call Answers with
SearchSecurities(ctx, query, &SearchSecuritiesParams{Limit}) []SecuritySearchHit
Profile(ctx, ticker) SecurityProfile
Metrics(ctx, ticker, &MetricsParams{Period, Keys, Collapse, Limit, AsOf}) []MetricValue
MetricCatalog(ctx) []MetricCatalogEntry
MetricLineage(ctx, ticker, key, &MetricLineageParams{MetricValueID, Limit, AsOf}) []MetricLineage
MetricRevisions(ctx, ticker, key, &MetricRevisionsParams{MetricValueID, FiscalYear, FiscalPeriod, Limit}) []MetricRevision
RawConcepts(ctx, ticker, &RawConceptsParams{Limit}) []RawConcept
Filings(ctx, ticker, &FilingsParams{Forms, Items, Limit}) []Filing
FilingsDay(ctx, &FilingsDayParams{Date}) FilingsDay
Filing(ctx, accession) FilingSource
InsiderActivity(ctx, &InsiderActivityParams{Ticker, Tickers, Since, Kind, Limit, Offset}) InsiderActivityPage
SearchHolders(ctx, &SearchHoldersParams{Query, Limit}) []HolderHit
Holder(ctx, cik, &HolderParams{Limit, Offset}) Holder
Holders(ctx, ticker, &HoldersParams{Limit, Offset}) SecurityHolders
Segments(ctx, ticker, &SegmentsParams{Period}) Segments
Prices(ctx, ticker, &PricesParams{Range, From, To}) Prices
Screen(ctx, &ScreenParams{Where, Sort, Dir, Limit, Offset, Columns}) []ScreenRow
Release(ctx) Release

Each answers with a *Response: .Data as above, .Meta (the route, the parameters as the API read them, the Screener’s counts, the release), .RequestID, .ETag, .RateLimit and .Header.

The Screener

big := &thaler.ScreenParams{
	Where: []thaler.Clause{
		thaler.Where(thaler.ScreenColumnRevenue, thaler.Gte, 10_000_000_000),
		thaler.Where(thaler.ScreenColumnNetMargin, thaler.Gt, 0.2),
	},
	Sort:    thaler.ScreenColumnRevenue,
	Dir:     thaler.SortDirectionDesc,
	Columns: []thaler.ScreenColumn{thaler.ScreenColumnRevenue, thaler.ScreenColumnNetMargin, thaler.ScreenColumnMarketCap},
}
page, err := client.Screen(ctx, big)
if err != nil {
	return err
}
for _, row := range page.Data {
	fmt.Println(row.Ticker, row.Revenue, row.NetMargin)
}
fmt.Println(*page.Meta.Total, "matches")

for row, err := range client.ScreenAll(ctx, &thaler.ScreenParams{
	Where: []thaler.Clause{thaler.Where(thaler.ScreenColumnFCFMargin, thaler.Gte, 0.15)},
}) {
	if err != nil {
		return err
	}
	fmt.Println(row.Ticker)
}

Where writes a clause as the API takes it (revenue:gte:10000000000, never scientific notation); a Clause written by hand works as well.

Point-in-time reads

then, err := client.Metrics(ctx, "KHC", &thaler.MetricsParams{
	Period: thaler.MetricPeriodAnnual,
	Keys:   []string{"net_income"},
	AsOf:   thaler.NewDate(2019, time.March, 1),
})
now, err := client.Metrics(ctx, "KHC", &thaler.MetricsParams{
	Period: thaler.MetricPeriodAnnual,
	Keys:   []string{"net_income"},
})

Each value comes from the latest filing on or before the day, so a backtest only sees what was public at the time. See the guide on point-in-time data.

Errors

profile, err := client.Profile(ctx, "ZZZZ")
var apiErr *thaler.APIError
var transportErr *thaler.TransportError
switch {
case errors.As(err, &apiErr) && apiErr.Kind() == thaler.ErrorNotFound:
	fmt.Println(apiErr.Code, apiErr.Detail, apiErr.RequestID)
case errors.As(err, &apiErr) && apiErr.Kind() == thaler.ErrorRateLimited:
	fmt.Println("wait", apiErr.RetryAfter, apiErr.ViolatedPolicies)
case errors.As(err, &apiErr):
	fmt.Println(apiErr.Status, apiErr.Code)
case errors.As(err, &transportErr):
	fmt.Println("no answer:", transportErr.Err)
case err != nil:
	return err
default:
	fmt.Println(profile.Data.EntityName)
}

Prices

Prices include IEX’s last sale for each trading day. Data provided for free by IEX. By accessing or using IEX Historical Data, you agree to the IEX Historical Data Terms of Use.

Versions

The module is v0.x while the API is in beta. thaler.APIVersion names the API document a release follows. Changes are in CHANGELOG.md.

Documentation

Overview

Package thaler is the Thaler API from Go: financial data from SEC filings, with the source filing for every value.

client, err := thaler.New() // THALER_API_KEY; or thaler.WithAPIKey("thaler_…")
if err != nil {
	log.Fatal(err)
}
rows, err := client.Metrics(ctx, "AAPL", &thaler.MetricsParams{
	Period: thaler.MetricPeriodAnnual,
	Keys:   []string{"revenue", "net_income"},
})
if err != nil {
	log.Fatal(err)
}
for _, row := range rows.Data {
	fmt.Println(row.EndDate, row.MetricKey, row.Value)
}

Every figure is a Decimal (the digits as filed, never a float that loses digits past the fifteenth), every day a Date, every instant a time.Time, and every answer a Response carrying the request ID and the account's limits beside its Data. The client keeps at most four requests in flight, waits when the minute's limit is spent, retries a 429 after its Retry-After and a 500, 502, 503 or 504 after a growing pause, and returns a typed error for the rest: an *APIError for an answer the API gave, a *TransportError when there was none, a *DecodeError when the answer is not as documented.

The types in types.go are generated from the API's OpenAPI document; APIVersion names the document they came from.

Index

Constants

View Source
const APIVersion = "1.0.0-beta.2"

APIVersion is the version of the API document these types were generated from.

View Source
const DefaultBaseURL = "https://api.thaler.sh"

DefaultBaseURL is where the API lives.

View Source
const UserAgent = "thaler-go/" + Version

UserAgent is what the client announces itself as: thaler-go/<version>.

View Source
const Version = "0.1.0"

Version is the module's version, as the User-Agent announces it.

Variables

AnnouncementTimingValues lists every value the document names, in its order.

AxisValues lists every value the document names, in its order.

InsiderFormValues lists every value the document names, in its order.

InsiderKindValues lists every value the document names, in its order.

LimitPolicyValues lists every value the document names, in its order.

MatchQualityValues lists every value the document names, in its order.

MeasureValues lists every value the document names, in its order.

MetricPeriodValues lists every value the document names, in its order.

PriceActionKindValues lists every value the document names, in its order.

PriceRangeValues lists every value the document names, in its order.

PriceSourceValues lists every value the document names, in its order.

ProblemCodeValues lists every value the document names, in its order.

ReleaseChecksValues lists every value the document names, in its order.

RevisionKindValues lists every value the document names, in its order.

View Source
var ScreenColumnValues = []ScreenColumn{
	ScreenColumnCoverageState,
	ScreenColumnFiscalYear,
	ScreenColumnAnnualEndDate,
	ScreenColumnInstantEndDate,
	ScreenColumnPriorAnnualEndDate,
	ScreenColumnPublicFloatEndDate,
	ScreenColumnSharesOutstandingEndDate,
	ScreenColumnRevenue,
	ScreenColumnGrossProfit,
	ScreenColumnOperatingIncome,
	ScreenColumnNetIncome,
	ScreenColumnEPSDiluted,
	ScreenColumnOperatingCashFlow,
	ScreenColumnCapitalExpenditures,
	ScreenColumnFreeCashFlow,
	ScreenColumnShareBasedCompensation,
	ScreenColumnDepreciationAndAmortization,
	ScreenColumnRevenuePrior,
	ScreenColumnNetIncomePrior,
	ScreenColumnAssets,
	ScreenColumnCurrentAssets,
	ScreenColumnCashAndEquivalents,
	ScreenColumnLiabilities,
	ScreenColumnCurrentLiabilities,
	ScreenColumnStockholdersEquity,
	ScreenColumnCommonSharesOutstanding,
	ScreenColumnPublicFloat,
	ScreenColumnGrossMargin,
	ScreenColumnOperatingMargin,
	ScreenColumnNetMargin,
	ScreenColumnFCFMargin,
	ScreenColumnROE,
	ScreenColumnROA,
	ScreenColumnCurrentRatio,
	ScreenColumnCashRatio,
	ScreenColumnLiabilitiesToEquity,
	ScreenColumnRevenueYOY,
	ScreenColumnNetIncomeYOY,
	ScreenColumnCapexIntensity,
	ScreenColumnSBCIntensity,
	ScreenColumnDividendsPaid,
	ScreenColumnShareRepurchases,
	ScreenColumnDividendsPerShare,
	ScreenColumnCapitalReturns,
	ScreenColumnPayoutRatio,
	ScreenColumnCapitalReturnsToFCF,
	ScreenColumnSharesChange,
	ScreenColumnPrice,
	ScreenColumnPriceDay,
	ScreenColumnMarketCap,
	ScreenColumnPE,
	ScreenColumnPS,
	ScreenColumnPB,
	ScreenColumnFCFYield,
	ScreenColumnDividendYield,
	ScreenColumnTTMEndDate,
	ScreenColumnRevenueTTM,
	ScreenColumnNetIncomeTTM,
	ScreenColumnOperatingCashFlowTTM,
	ScreenColumnFreeCashFlowTTM,
	ScreenColumnPETTM,
	ScreenColumnPSTTM,
	ScreenColumnFCFYieldTTM,
}

ScreenColumnValues lists every value the document names, in its order.

SegmentsPeriodValues lists every value the document names, in its order.

View Source
var SortDirectionValues = []SortDirection{
	SortDirectionAsc,
	SortDirectionDesc,
}

SortDirectionValues lists every value the document names, in its order.

View Source
var TradeKindValues = []TradeKind{
	TradeKindPurchase,
	TradeKindSale,
}

TradeKindValues lists every value the document names, in its order.

TransactionCodeValues lists every value the document names, in its order.

ValueKindValues lists every value the document names, in its order.

ValueStatusValues lists every value the document names, in its order.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	// Status is the HTTP status.
	Status int
	// Code is the problem's code, as the errors page lists them; a code
	// this version of the SDK does not know still reads.
	Code ProblemCode
	// Title is the problem's title.
	Title string
	// Detail is what went wrong and what to do, in a sentence or two.
	Detail string
	// Type is the URL of the code's entry on the errors page.
	Type string
	// RequestID is the request's ID; quote it when writing to support.
	RequestID string
	// RetryAfter is how long to wait before trying again, when the API
	// said; zero otherwise.
	RetryAfter time.Duration
	// ViolatedPolicies is, on a 429, the limits the request would have
	// broken.
	ViolatedPolicies []LimitPolicy
	// RateLimit is the account's limits as the answer reported them.
	RateLimit *RateLimit
	// Header is the answer's headers.
	Header http.Header
}

APIError is an error the API answered with, as an RFC 9457 problem, as documented at https://thaler.sh/developers/errors. Read it with errors.As:

var apiErr *thaler.APIError
if errors.As(err, &apiErr) && apiErr.Kind() == thaler.ErrorNotFound {
	// Thaler doesn't cover the ticker
}

func (*APIError) Error

func (e *APIError) Error() string

Error is the code, the status, the detail and the request ID.

func (*APIError) Kind

func (e *APIError) Kind() ErrorKind

Kind is what the error is, by its status.

type AnnouncementTiming

type AnnouncementTiming string

AnnouncementTiming: When in the trading day an announcement was accepted.

const (
	AnnouncementTimingBeforeOpen   AnnouncementTiming = "before_open"
	AnnouncementTimingDuringMarket AnnouncementTiming = "during_market"
	AnnouncementTimingAfterClose   AnnouncementTiming = "after_close"
)

type Attribution

type Attribution struct {
	// Text: The sentence to show.
	Text string `json:"text"`
	// URL: The terms it points to.
	URL string `json:"url"`
}

Attribution: as the API sends it.

type Axis

type Axis string

Axis: How a company breaks its figures down.

const (
	AxisSegment   Axis = "segment"
	AxisGeography Axis = "geography"
	AxisProduct   Axis = "product"
)

type Clause

type Clause struct {
	Column ScreenColumn
	Op     Op
	// Value is a plain decimal: digits, a sign and a fraction, never an
	// exponent, at most 32 characters.
	Value string
}

Clause is a filter for the Screener: a column, an operator and a value, column:op:value on the wire. Where writes one from a number; one written by hand works as well:

thaler.Clause{Column: thaler.ScreenColumnNetMargin, Op: thaler.Gt, Value: "0.2"}

Before a clause is sent it is checked as the API's own parser checks it, so one the API would refuse is an error before a counted request.

func Where

func Where[V Number](column ScreenColumn, op Op, value V) Clause

Where is a clause from a column, an operator and a number:

thaler.Where(thaler.ScreenColumnRevenue, thaler.Gte, 1_000_000_000)   // revenue:gte:1000000000
thaler.Where(thaler.ScreenColumnNetMargin, thaler.Gt, 0.2)            // net_margin:gt:0.2

The value is written as a plain decimal, never in scientific notation.

func (Clause) String

func (c Clause) String() string

String is the clause as the API takes it.

type Client

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

Client is the Thaler API. One serves a whole program: it is safe for concurrent use, and it is what keeps the account inside its limits.

func New

func New(options ...Option) (*Client, error)

New is a client with these options, or an error when there is no key or it is not a Thaler API key.

func (*Client) BaseURL

func (c *Client) BaseURL() string

BaseURL is where the client sends.

func (*Client) Filing

func (c *Client) Filing(ctx context.Context, accession string) (*Response[FilingSource], error)

Filing is a filing by accession number, with its documents.

func (*Client) Filings

func (c *Client) Filings(ctx context.Context, ticker string, params *FilingsParams) (*Response[[]Filing], error)

Filings is a company's filings, newest first.

func (*Client) FilingsDay

func (c *Client) FilingsDay(ctx context.Context, params *FilingsDayParams) (*Response[FilingsDay], error)

FilingsDay is one day of filings across every covered company.

func (*Client) Holder

func (c *Client) Holder(ctx context.Context, cik int64, params *HolderParams) (*Response[Holder], error)

Holder is what one manager holds, by CIK, quarter over quarter.

func (*Client) HolderPositionsAll

func (c *Client) HolderPositionsAll(ctx context.Context, cik int64, params *HolderParams) iter.Seq2[HolderPosition, error]

HolderPositionsAll is every position a manager holds, page after page. Pages are params.Limit rows, 500 when unset.

func (*Client) Holders

func (c *Client) Holders(ctx context.Context, ticker string, params *HoldersParams) (*Response[SecurityHolders], error)

Holders is a company's institutional holders this quarter, against the previous one.

func (*Client) HoldersAll

func (c *Client) HoldersAll(ctx context.Context, ticker string, params *HoldersParams) iter.Seq2[SecurityHolder, error]

HoldersAll is every institutional holder of a company this quarter, page after page. Pages are params.Limit rows, 200 when unset.

func (*Client) InsiderActivity

func (c *Client) InsiderActivity(ctx context.Context, params *InsiderActivityParams) (*Response[InsiderActivityPage], error)

InsiderActivity is open-market purchases and sales from Forms 4 and 5: one company's with Ticker, several companies' with Tickers, or every covered company's.

func (*Client) InsiderFilingsAll

func (c *Client) InsiderFilingsAll(ctx context.Context, params *InsiderActivityParams) iter.Seq2[InsiderFiling, error]

InsiderFilingsAll is every ownership filing with open-market trades, newest first, page after page. Pages are params.Limit filings, 100 when unset.

func (*Client) MetricCatalog

func (c *Client) MetricCatalog(ctx context.Context) (*Response[[]MetricCatalogEntry], error)

MetricCatalog lists every metric key, with its label and statement.

func (*Client) MetricLineage

func (c *Client) MetricLineage(ctx context.Context, ticker, metricKey string, params *MetricLineageParams) (*Response[[]MetricLineage], error)

MetricLineage is the XBRL facts behind a metric's values.

func (*Client) MetricRevisions

func (c *Client) MetricRevisions(ctx context.Context, ticker, metricKey string, params *MetricRevisionsParams) (*Response[[]MetricRevision], error)

MetricRevisions is every filing's statement of a metric's figures.

func (*Client) Metrics

func (c *Client) Metrics(ctx context.Context, ticker string, params *MetricsParams) (*Response[[]MetricValue], error)

Metrics is a company's metric values, each with the filing it was read from.

func (*Client) Prices

func (c *Client) Prices(ctx context.Context, ticker string, params *PricesParams) (*Response[Prices], error)

Prices is a company's prices: IEX's last sale each trading day, the closes of record, the latest price and market cap.

func (*Client) Profile

func (c *Client) Profile(ctx context.Context, ticker string) (*Response[SecurityProfile], error)

Profile is a company's profile: its listing, coverage and latest price.

func (*Client) RateLimit

func (c *Client) RateLimit() *RateLimit

RateLimit is the account's limits as the last answer reported them, or nil before the first.

func (*Client) RawConcepts

func (c *Client) RawConcepts(ctx context.Context, ticker string, params *RawConceptsParams) (*Response[[]RawConcept], error)

RawConcepts is the XBRL concepts a company reports.

func (*Client) Release

func (c *Client) Release(ctx context.Context) (*Response[Release], error)

Release is the data release being served, and its checks.

func (*Client) Screen

func (c *Client) Screen(ctx context.Context, params *ScreenParams) (*Response[[]ScreenRow], error)

Screen is the Screener: every covered company, filtered and sorted by its figures.

func (*Client) ScreenAll

func (c *Client) ScreenAll(ctx context.Context, params *ScreenParams) iter.Seq2[ScreenRow, error]

ScreenAll is every row the Screener matches, page after page, from params.Offset on. Pages are params.Limit rows, 500 when unset. An error ends the sequence; it is the last pair's.

for row, err := range client.ScreenAll(ctx, &thaler.ScreenParams{Where: clauses}) {
	if err != nil {
		return err
	}
	fmt.Println(row.Ticker, row.Revenue)
}

func (*Client) SearchHolders

func (c *Client) SearchHolders(ctx context.Context, params *SearchHoldersParams) (*Response[[]HolderHit], error)

SearchHolders lists institutional managers by name, or the largest.

func (*Client) SearchSecurities

func (c *Client) SearchSecurities(ctx context.Context, query string, params *SearchSecuritiesParams) (*Response[[]SecuritySearchHit], error)

SearchSecurities lists companies by name or ticker.

func (*Client) Segments

func (c *Client) Segments(ctx context.Context, ticker string, params *SegmentsParams) (*Response[Segments], error)

Segments is revenue and operating income by business segment, geography and product.

type Date

type Date struct {
	Year  int
	Month time.Month
	Day   int
}

Date is a calendar day as the API sends it, YYYY-MM-DD, with no time and no zone: a fiscal period's end, a filing date, a trading day.

func DateOf

func DateOf(t time.Time) Date

DateOf is the day of a time, in the time's own location.

func NewDate

func NewDate(year int, month time.Month, day int) Date

NewDate is the day with these parts.

func ParseDate

func ParseDate(text string) (Date, error)

ParseDate reads YYYY-MM-DD.

func (Date) AddDays

func (d Date) AddDays(days int) Date

AddDays is the day this many days later (or earlier, when negative).

func (Date) After

func (d Date) After(other Date) bool

After reports whether d is after other.

func (Date) Before

func (d Date) Before(other Date) bool

Before reports whether d is before other.

func (Date) Compare

func (d Date) Compare(other Date) int

Compare is -1, 0 or +1 as d is before, the same as, or after other.

func (Date) IsValid

func (d Date) IsValid() bool

IsValid reports whether the parts name a day of the calendar.

func (Date) IsZero

func (d Date) IsZero() bool

IsZero reports whether the date is the zero value, the way an unset parameter is.

func (Date) MarshalText

func (d Date) MarshalText() ([]byte, error)

MarshalText writes YYYY-MM-DD.

func (Date) String

func (d Date) String() string

String is the day as YYYY-MM-DD.

func (Date) Time

func (d Date) Time() time.Time

Time is midnight at the start of the day, in UTC.

func (*Date) UnmarshalText

func (d *Date) UnmarshalText(text []byte) error

UnmarshalText reads YYYY-MM-DD. Text that is not a day is reported as encoding/json reports a mistyped value, so the error names the field.

type Decimal

type Decimal string

Decimal is a figure as the API sends it: a decimal string such as "416161000000", "39.75", "-58000000" or "0.3018", exact to the digit as filed. The API never sends a number, because a double loses digits past the fifteenth; this keeps the digits and lets you parse them into the arithmetic type you use: Decimal.Rat for exact arithmetic with the standard library, Decimal.Float64 when a double will do.

func ParseDecimal

func ParseDecimal(text string) (Decimal, error)

ParseDecimal checks that text is a decimal string: digits, a sign and a fraction, never an exponent.

func (Decimal) Float64

func (d Decimal) Float64() (float64, error)

Float64 is the figure as a double, rounded past the fifteenth digit.

func (Decimal) Int64

func (d Decimal) Int64() (int64, error)

Int64 is the figure when it is a whole number that fits.

func (Decimal) IsNegative

func (d Decimal) IsNegative() bool

IsNegative reports whether the figure is below zero.

func (Decimal) IsValid

func (d Decimal) IsValid() bool

IsValid reports whether the text is a decimal string.

func (Decimal) MarshalJSON

func (d Decimal) MarshalJSON() ([]byte, error)

MarshalJSON writes the figure as a JSON string.

func (Decimal) Rat

func (d Decimal) Rat() (*big.Rat, error)

Rat is the figure as an exact rational, for arithmetic that keeps every digit.

func (Decimal) String

func (d Decimal) String() string

String is the digits as the API sent them.

func (*Decimal) UnmarshalJSON

func (d *Decimal) UnmarshalJSON(data []byte) error

UnmarshalJSON reads a JSON string and checks it is a decimal string. A value that is not one is reported as encoding/json reports a mistyped value, so the error names the field.

type DecodeError

type DecodeError struct {
	// Operation is the API operation that was asked for.
	Operation string
	// Field is the field that was wrong, as data.cik, when known.
	Field string
	// RequestID is the answer's request ID.
	RequestID string
	// Err is what the decoder reported.
	Err error
}

DecodeError means an answer is not as the API documents it. Write to support@thaler.sh with it, quoting the request ID.

func (*DecodeError) Error

func (e *DecodeError) Error() string

Error names the operation, the field and the cause.

func (*DecodeError) Unwrap

func (e *DecodeError) Unwrap() error

Unwrap is the cause.

type ErrorKind

type ErrorKind int

ErrorKind is what an APIError is, by its status.

const (
	// ErrorOther is another status, such as 405.
	ErrorOther ErrorKind = iota
	// ErrorBadRequest is a 400: a parameter is missing, unknown or out of
	// range; Detail names it.
	ErrorBadRequest
	// ErrorAuthentication is a 401: no key, or a key that is malformed,
	// unknown, revoked or expired; Code says which.
	ErrorAuthentication
	// ErrorNotFound is a 404: no such endpoint, company, filing, holder or
	// day. On a ticker route, Thaler doesn't cover the ticker.
	ErrorNotFound
	// ErrorRateLimited is a 429: a limit was reached and the retries ran
	// out, or RetryAfter was past what the client waits for.
	// ViolatedPolicies names the limits; the request wasn't counted.
	ErrorRateLimited
	// ErrorServer is a 5xx: Thaler failed to answer, is busy, or took too
	// long. A 500, 502, 503 or 504 is returned only after the retries.
	// The request wasn't counted.
	ErrorServer
)

func (ErrorKind) String

func (k ErrorKind) String() string

String names the kind.

type FactLocation

type FactLocation struct {
	Concept      *string      `json:"concept"`
	Context      *string      `json:"context"`
	Document     *string      `json:"document"`
	LineID       *string      `json:"line_id"`
	MatchQuality MatchQuality `json:"match_quality"`
}

FactLocation: as the API sends it.

type Filing

type Filing struct {
	// AcceptedAt: When EDGAR accepted the filing; for an announcement, the moment
	// it went public.
	AcceptedAt      *time.Time `json:"accepted_at"`
	AccessionNumber string     `json:"accession_number"`
	// AnnouncementTiming: Session slot of an earnings announcement against the
	// New York trading day (09:30 to 16:00 Eastern); null for every other filing.
	AnnouncementTiming *AnnouncementTiming `json:"announcement_timing"`
	CIK                int64               `json:"cik"`
	EntityName         string              `json:"entity_name"`
	Exchange           *string             `json:"exchange"`
	FiledAt            *Date               `json:"filed_at"`
	FiscalPeriod       *string             `json:"fiscal_period"`
	FiscalYear         *int64              `json:"fiscal_year"`
	Form               string              `json:"form"`
	// Items: 8-K item numbers as EDGAR lists them (an earnings announcement is
	// furnished under 2.02); empty for other forms.
	Items           []string `json:"items"`
	PrimaryDocument *string  `json:"primary_document"`
	ReportDate      *Date    `json:"report_date"`
	SourceURL       *string  `json:"source_url"`
	Ticker          *string  `json:"ticker"`
}

Filing: as the API sends it.

type FilingSource

type FilingSource struct {
	AcceptedAt      *time.Time `json:"accepted_at"`
	AccessionNumber string     `json:"accession_number"`
	CIK             int64      `json:"cik"`
	// Documents: Its documents: the form's own document first, then the exhibits
	// Thaler read.
	Documents  []FilingSourceDocument `json:"documents"`
	EntityName string                 `json:"entity_name"`
	FiledAt    *Date                  `json:"filed_at"`
	// Folder: The filing's folder on EDGAR, with a trailing slash.
	Folder string  `json:"folder"`
	Form   string  `json:"form"`
	Ticker *string `json:"ticker"`
}

FilingSource: as the API sends it.

type FilingSourceDocument

type FilingSourceDocument struct {
	// Document: The file's name in the filing's folder.
	Document string `json:"document"`
	// Kind: The document's type as filed: the form code, or an exhibit number.
	Kind string `json:"kind"`
	// Read: Whether Thaler has read this document.
	Read bool   `json:"read"`
	URL  string `json:"url"`
}

FilingSourceDocument: as the API sends it.

type FilingSourceEnvelope

type FilingSourceEnvelope struct {
	Data FilingSource `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

FilingSourceEnvelope: as the API sends it.

type FilingsDay

type FilingsDay struct {
	// Companies: How many companies made them.
	Companies int64 `json:"companies"`
	// Date: The day shown.
	Date Date `json:"date"`
	// Days: Filings per day over the fourteen days ending on the day shown,
	// oldest first; days without filings are absent.
	Days []FilingsDayCount `json:"days"`
	// Filings: Every filing the covered universe made that day.
	Filings int64 `json:"filings"`
	// Forms: Every form filed that day with its count, most filed first.
	Forms    []FilingsDayForm   `json:"forms"`
	Insiders FilingsDayInsiders `json:"insiders"`
	// Latest: The most recent day with filings on file.
	Latest Date `json:"latest"`
	// Lines: Current reports and event notices, earliest acceptance first, capped
	// at 1500.
	Lines []Filing `json:"lines"`
	// LinesTotal: How many lines the day owed; larger than the lines carried only
	// past the cap.
	LinesTotal int64 `json:"lines_total"`
	// Live: The day is today in New York and the wire is still adding to it.
	Live    *bool              `json:"live"`
	Reports []FilingsDayReport `json:"reports"`
	// UpdatedAt: When EDGAR accepted the day's latest filing on file.
	UpdatedAt *time.Time `json:"updated_at"`
}

FilingsDay: as the API sends it.

type FilingsDayCount

type FilingsDayCount struct {
	Date    Date  `json:"date"`
	Filings int64 `json:"filings"`
}

FilingsDayCount: as the API sends it.

type FilingsDayEnvelope

type FilingsDayEnvelope struct {
	Data FilingsDay   `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

FilingsDayEnvelope: as the API sends it.

type FilingsDayForm

type FilingsDayForm struct {
	Filings int64  `json:"filings"`
	Form    string `json:"form"`
}

FilingsDayForm: as the API sends it.

type FilingsDayInsiders

type FilingsDayInsiders struct {
	// Largest: The day's largest trades by value, largest first, one per filing
	// and side.
	Largest       []FilingsDayTrade `json:"largest"`
	PurchaseValue Decimal           `json:"purchase_value"`
	// Purchases: Filings reporting open-market purchases.
	Purchases int64   `json:"purchases"`
	SaleValue Decimal `json:"sale_value"`
	// Sales: Filings reporting open-market sales.
	Sales int64 `json:"sales"`
}

FilingsDayInsiders: as the API sends it.

type FilingsDayParams

type FilingsDayParams struct {
	// Date is the day to read; the latest with filings by default.
	Date Date
}

FilingsDayParams are the options of Client.FilingsDay.

type FilingsDayReport

type FilingsDayReport struct {
	AcceptedAt      *time.Time `json:"accepted_at"`
	AccessionNumber string     `json:"accession_number"`
	CIK             int64      `json:"cik"`
	EntityName      string     `json:"entity_name"`
	Exchange        *string    `json:"exchange"`
	FiscalPeriod    *string    `json:"fiscal_period"`
	FiscalYear      *int64     `json:"fiscal_year"`
	Form            string     `json:"form"`
	// PriorRevenue: Revenue for the matching period a year earlier, when on file.
	PriorRevenue *Decimal `json:"prior_revenue"`
	ReportDate   *Date    `json:"report_date"`
	// Revenue: Revenue for the period the report covers, as reported, when the
	// ledger already holds it.
	Revenue      *Decimal `json:"revenue"`
	RevenueEnd   *Date    `json:"revenue_end"`
	RevenueStart *Date    `json:"revenue_start"`
	SourceURL    *string  `json:"source_url"`
	Ticker       *string  `json:"ticker"`
}

FilingsDayReport: as the API sends it.

type FilingsDayTrade

type FilingsDayTrade struct {
	AccessionNumber   string    `json:"accession_number"`
	CIK               int64     `json:"cik"`
	EntityName        string    `json:"entity_name"`
	IsDirector        bool      `json:"is_director"`
	IsOfficer         bool      `json:"is_officer"`
	IsTenPercentOwner bool      `json:"is_ten_percent_owner"`
	Kind              TradeKind `json:"kind"`
	OfficerTitle      *string   `json:"officer_title"`
	OwnerName         *string   `json:"owner_name"`
	Shares            Decimal   `json:"shares"`
	SourceURL         string    `json:"source_url"`
	Ticker            *string   `json:"ticker"`
	Value             Decimal   `json:"value"`
}

FilingsDayTrade: as the API sends it.

type FilingsEnvelope

type FilingsEnvelope struct {
	Data []Filing     `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

FilingsEnvelope: as the API sends it.

type FilingsParams

type FilingsParams struct {
	// Forms narrows to these forms, such as 10-K or 8-K.
	Forms []string
	// Items narrows to 8-Ks with these items, such as 2.02.
	Items []string
	// Limit is at most this many filings.
	Limit int
}

FilingsParams are the options of Client.Filings.

type Holder

type Holder struct {
	AccessionNumber string `json:"accession_number"`
	CIK             int64  `json:"cik"`
	Closed          *int64 `json:"closed"`
	FiledAt         Date   `json:"filed_at"`
	Name            string `json:"name"`
	// Opened: Null when the manager has no earlier report on the ledger.
	Opened        *int64           `json:"opened"`
	OtherManagers int64            `json:"other_managers"`
	Period        Date             `json:"period"`
	Positions     int64            `json:"positions"`
	PriorPeriod   *Date            `json:"prior_period"`
	Quarters      []HolderQuarter  `json:"quarters"`
	Rows          []HolderPosition `json:"rows"`
	RowsTotal     int64            `json:"rows_total"`
	// ValueTotal: Dollars.
	ValueTotal Decimal `json:"value_total"`
}

Holder: as the API sends it.

type HolderEnvelope

type HolderEnvelope struct {
	Data Holder       `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

HolderEnvelope: as the API sends it.

type HolderHit

type HolderHit struct {
	CIK             int64    `json:"cik"`
	LatestPeriod    *Date    `json:"latest_period"`
	LatestPositions *int64   `json:"latest_positions"`
	LatestValue     *Decimal `json:"latest_value"`
	Name            string   `json:"name"`
}

HolderHit: as the API sends it.

type HolderHitsEnvelope

type HolderHitsEnvelope struct {
	Data []HolderHit  `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

HolderHitsEnvelope: as the API sends it.

type HolderParams

type HolderParams struct {
	// Limit is at most this many positions, 100 by default and 500 at
	// most.
	Limit int
	// Offset skips this many positions.
	Offset int
}

HolderParams are the options of Client.Holder.

type HolderPosition

type HolderPosition struct {
	Amount     Decimal `json:"amount"`
	AmountType string  `json:"amount_type"`
	CIK        *int64  `json:"cik"`
	Class      string  `json:"class"`
	CUSIP      string  `json:"cusip"`
	EntityName *string `json:"entity_name"`
	// Issuer: As the manager names it.
	Issuer      string   `json:"issuer"`
	PriorAmount *Decimal `json:"prior_amount"`
	PriorValue  *Decimal `json:"prior_value"`
	// PutCall: Put, Call, or empty.
	PutCall string   `json:"put_call"`
	Ticker  *string  `json:"ticker"`
	Value   Decimal  `json:"value"`
	Weight  *Decimal `json:"weight"`
}

HolderPosition: as the API sends it.

type HolderQuarter

type HolderQuarter struct {
	AccessionNumber string  `json:"accession_number"`
	FiledAt         Date    `json:"filed_at"`
	Period          Date    `json:"period"`
	Positions       int64   `json:"positions"`
	ValueTotal      Decimal `json:"value_total"`
}

HolderQuarter: as the API sends it.

type HoldersParams

type HoldersParams struct {
	// Limit is at most this many holders, 50 by default and 200 at most.
	Limit int
	// Offset skips this many holders.
	Offset int
}

HoldersParams are the options of Client.Holders.

type InsiderActivityEnvelope

type InsiderActivityEnvelope struct {
	Data InsiderActivityPage `json:"data"`
	Meta ResponseMeta        `json:"meta"`
}

InsiderActivityEnvelope: as the API sends it.

type InsiderActivityPage

type InsiderActivityPage struct {
	Filings              []InsiderFiling `json:"filings"`
	PurchaseTransactions int64           `json:"purchase_transactions"`
	// ReportedPurchaseValue: Shares × price over counted rows, each distinct
	// trade once however many filers reported it.
	ReportedPurchaseValue Decimal `json:"reported_purchase_value"`
	// ReportedSaleValue: Shares × price over counted rows, each distinct trade
	// once however many filers reported it.
	ReportedSaleValue Decimal `json:"reported_sale_value"`
	SaleTransactions  int64   `json:"sale_transactions"`
	TotalTransactions int64   `json:"total_transactions"`
	// UncountedTransactions: Rows listed but left out of the values: a filed
	// price that fails a plausibility check, or a security that is not common
	// equity.
	UncountedTransactions int64 `json:"uncounted_transactions"`
}

InsiderActivityPage: as the API sends it.

type InsiderActivityParams

type InsiderActivityParams struct {
	// Ticker reads one company's trades, on the company's own route.
	Ticker string
	// Tickers reads several companies' trades, at most sixty. Not with
	// Ticker.
	Tickers []string
	// Since is transactions on or after this reported transaction date.
	Since Date
	// Kind is purchases, sales, or all.
	Kind InsiderKind
	// Limit is at most this many ownership filings, 25 by default and
	// 100 at most.
	Limit int
	// Offset skips this many filings.
	Offset int
}

InsiderActivityParams are the options of Client.InsiderActivity.

type InsiderFiling

type InsiderFiling struct {
	AccessionNumber string               `json:"accession_number"`
	Aff10b5One      *bool                `json:"aff10b5_one"`
	CIK             int64                `json:"cik"`
	EntityName      string               `json:"entity_name"`
	FiledAt         *Date                `json:"filed_at"`
	Footnotes       []InsiderFootnote    `json:"footnotes"`
	Form            InsiderForm          `json:"form"`
	IsAmendment     bool                 `json:"is_amendment"`
	Owners          []InsiderOwner       `json:"owners"`
	PeriodOfReport  *Date                `json:"period_of_report"`
	SourceURL       string               `json:"source_url"`
	Ticker          *string              `json:"ticker"`
	Transactions    []InsiderTransaction `json:"transactions"`
}

InsiderFiling: as the API sends it.

type InsiderFootnote

type InsiderFootnote struct {
	ID   string `json:"id"`
	Text string `json:"text"`
}

InsiderFootnote: as the API sends it.

type InsiderForm

type InsiderForm string

InsiderForm: The ownership form a transaction was reported on.

const (
	InsiderFormForm4  InsiderForm = "4"
	InsiderFormForm4A InsiderForm = "4/A"
	InsiderFormForm5  InsiderForm = "5"
	InsiderFormForm5A InsiderForm = "5/A"
)

type InsiderKind

type InsiderKind string

InsiderKind: Which insider transactions to read.

const (
	InsiderKindAll      InsiderKind = "all"
	InsiderKindPurchase InsiderKind = "purchase"
	InsiderKindSale     InsiderKind = "sale"
)

type InsiderOwner

type InsiderOwner struct {
	CIK               int64   `json:"cik"`
	IsDirector        bool    `json:"is_director"`
	IsOfficer         bool    `json:"is_officer"`
	IsOther           bool    `json:"is_other"`
	IsTenPercentOwner bool    `json:"is_ten_percent_owner"`
	Name              string  `json:"name"`
	OfficerTitle      *string `json:"officer_title"`
	OtherText         *string `json:"other_text"`
}

InsiderOwner: as the API sends it.

type InsiderTransaction

type InsiderTransaction struct {
	AcquiredDisposedCode    *string         `json:"acquired_disposed_code"`
	DirectIndirectOwnership *string         `json:"direct_indirect_ownership"`
	FootnoteIDs             []string        `json:"footnote_ids"`
	NatureOfOwnership       *string         `json:"nature_of_ownership"`
	Ordinal                 int64           `json:"ordinal"`
	PricePerShare           *Decimal        `json:"price_per_share"`
	SecurityTitle           string          `json:"security_title"`
	Shares                  *Decimal        `json:"shares"`
	SharesOwnedFollowing    *Decimal        `json:"shares_owned_following"`
	TransactionCode         TransactionCode `json:"transaction_code"`
	TransactionDate         *Date           `json:"transaction_date"`
	TransactionValue        *Decimal        `json:"transaction_value"`
	// ValueStatus: Whether shares × price stands as filed (counted), fails a
	// plausibility check on the filed price (suspect), or is a security other
	// than common equity such as notes or preferred (not_equity). Only counted
	// rows enter the page's values.
	ValueStatus ValueStatus `json:"value_status"`
}

InsiderTransaction: as the API sends it.

type LimitPolicy

type LimitPolicy string

LimitPolicy: A limit an account can reach.

const (
	LimitPolicyMinute     LimitPolicy = "minute"
	LimitPolicyMonth      LimitPolicy = "month"
	LimitPolicyConcurrent LimitPolicy = "concurrent"
)

type MatchQuality

type MatchQuality string

MatchQuality: How surely a fact was located in its filing's document.

const (
	MatchQualityUnique     MatchQuality = "unique"
	MatchQualityAmbiguous  MatchQuality = "ambiguous"
	MatchQualityHiddenOnly MatchQuality = "hidden_only"
	MatchQualityNone       MatchQuality = "none"
)

type Measure

type Measure string

Measure: A figure a company reports by segment.

const (
	MeasureRevenue            Measure = "revenue"
	MeasureOperatingIncome    Measure = "operating_income"
	MeasureGrossProfit        Measure = "gross_profit"
	MeasureCostOfRevenue      Measure = "cost_of_revenue"
	MeasureAssets             Measure = "assets"
	MeasureLongLivedAssets    Measure = "long_lived_assets"
	MeasureCapitalExpenditure Measure = "capital_expenditure"
	MeasureDepreciation       Measure = "depreciation"
)

type MetricCatalogEntry

type MetricCatalogEntry struct {
	CoveredCompanyCount int64           `json:"covered_company_count"`
	Description         string          `json:"description"`
	Formula             *string         `json:"formula"`
	Key                 string          `json:"key"`
	Label               string          `json:"label"`
	Mappings            []MetricMapping `json:"mappings"`
	Statement           *string         `json:"statement"`
	Unit                *string         `json:"unit"`
	ValueKind           ValueKind       `json:"value_kind"`
}

MetricCatalogEntry: as the API sends it.

type MetricCatalogEnvelope

type MetricCatalogEnvelope struct {
	Data []MetricCatalogEntry `json:"data"`
	Meta ResponseMeta         `json:"meta"`
}

MetricCatalogEnvelope: as the API sends it.

type MetricLineage

type MetricLineage struct {
	AccessionNumber   *string       `json:"accession_number"`
	CIK               int64         `json:"cik"`
	Concept           string        `json:"concept"`
	EndDate           Date          `json:"end_date"`
	EntityName        string        `json:"entity_name"`
	Exchange          *string       `json:"exchange"`
	FiledAt           *Date         `json:"filed_at"`
	FiscalPeriod      *string       `json:"fiscal_period"`
	FiscalYear        *int64        `json:"fiscal_year"`
	Form              *string       `json:"form"`
	Frame             *string       `json:"frame"`
	Location          *FactLocation `json:"location"`
	MetricKey         string        `json:"metric_key"`
	MetricLabel       string        `json:"metric_label"`
	MetricUnit        string        `json:"metric_unit"`
	MetricValue       Decimal       `json:"metric_value"`
	MetricValueID     string        `json:"metric_value_id"`
	PeriodKind        string        `json:"period_kind"`
	RawFactID         string        `json:"raw_fact_id"`
	RawIngestionRunID *string       `json:"raw_ingestion_run_id"`
	RawUnit           string        `json:"raw_unit"`
	RawValue          Decimal       `json:"raw_value"`
	Role              string        `json:"role"`
	SourcePayloadID   *string       `json:"source_payload_id"`
	StartDate         *Date         `json:"start_date"`
	Taxonomy          string        `json:"taxonomy"`
	Ticker            *string       `json:"ticker"`
}

MetricLineage: as the API sends it.

type MetricLineageEnvelope

type MetricLineageEnvelope struct {
	Data []MetricLineage `json:"data"`
	Meta ResponseMeta    `json:"meta"`
}

MetricLineageEnvelope: as the API sends it.

type MetricLineageParams

type MetricLineageParams struct {
	// MetricValueID narrows to one value.
	MetricValueID string
	// Limit is at most this many rows.
	Limit int
	// AsOf reads the record as it stood on this day.
	AsOf Date
}

MetricLineageParams are the options of Client.MetricLineage.

type MetricMapping

type MetricMapping struct {
	Concept        string  `json:"concept"`
	Priority       int64   `json:"priority"`
	SignMultiplier int64   `json:"sign_multiplier"`
	Taxonomy       string  `json:"taxonomy"`
	Unit           *string `json:"unit"`
}

MetricMapping: as the API sends it.

type MetricPeriod

type MetricPeriod string

MetricPeriod: Which periods of a metric to read: the latest value of each, annual, quarterly, or all.

const (
	MetricPeriodLatest    MetricPeriod = "latest"
	MetricPeriodAnnual    MetricPeriod = "annual"
	MetricPeriodQuarterly MetricPeriod = "quarterly"
	MetricPeriodAll       MetricPeriod = "all"
)

type MetricRevision

type MetricRevision struct {
	AccessionNumber string `json:"accession_number"`
	CIK             int64  `json:"cik"`
	// Delta: value minus previous_value on a revised row; null otherwise.
	Delta         *Decimal     `json:"delta"`
	EndDate       Date         `json:"end_date"`
	EntityName    string       `json:"entity_name"`
	Exchange      *string      `json:"exchange"`
	FiledAt       *Date        `json:"filed_at"`
	FiscalPeriod  *string      `json:"fiscal_period"`
	FiscalYear    *int64       `json:"fiscal_year"`
	Form          *string      `json:"form"`
	Kind          RevisionKind `json:"kind"`
	MetricKey     string       `json:"metric_key"`
	MetricLabel   string       `json:"metric_label"`
	MetricUnit    string       `json:"metric_unit"`
	MetricValueID string       `json:"metric_value_id"`
	PeriodKind    string       `json:"period_kind"`
	PreviousValue *Decimal     `json:"previous_value"`
	RawFactID     string       `json:"raw_fact_id"`
	// RevisionRank: The filing's place in the chain, 1 for the earliest filing on
	// the ledger to state the figure.
	RevisionRank int64 `json:"revision_rank"`
	// SplitRatio: New shares per old share a re_expressed statement was
	// re-expressed by; null otherwise.
	SplitRatio *Decimal `json:"split_ratio"`
	// Standing: The statement whose fact is the metric value's source lineage.
	Standing  bool    `json:"standing"`
	StartDate *Date   `json:"start_date"`
	Ticker    *string `json:"ticker"`
	Value     Decimal `json:"value"`
}

MetricRevision: as the API sends it.

type MetricRevisionsEnvelope

type MetricRevisionsEnvelope struct {
	Data []MetricRevision `json:"data"`
	Meta ResponseMeta     `json:"meta"`
}

MetricRevisionsEnvelope: as the API sends it.

type MetricRevisionsParams

type MetricRevisionsParams struct {
	// MetricValueID narrows to one value.
	MetricValueID string
	// FiscalYear narrows to one fiscal year.
	FiscalYear int
	// FiscalPeriod narrows to one fiscal period, FY or Q1 to Q4.
	FiscalPeriod string
	// Limit is at most this many rows.
	Limit int
}

MetricRevisionsParams are the options of Client.MetricRevisions.

type MetricStatementRef

type MetricStatementRef struct {
	AccessionNumber string       `json:"accession_number"`
	FiledAt         *Date        `json:"filed_at"`
	Form            *string      `json:"form"`
	Kind            RevisionKind `json:"kind"`
	RevisionRank    int64        `json:"revision_rank"`
}

MetricStatementRef: as the API sends it.

type MetricValue

type MetricValue struct {
	CIK           int64   `json:"cik"`
	Confidence    Decimal `json:"confidence"`
	EndDate       Date    `json:"end_date"`
	EntityName    string  `json:"entity_name"`
	Exchange      *string `json:"exchange"`
	FiscalPeriod  *string `json:"fiscal_period"`
	FiscalYear    *int64  `json:"fiscal_year"`
	MetricKey     string  `json:"metric_key"`
	MetricLabel   string  `json:"metric_label"`
	MetricValueID string  `json:"metric_value_id"`
	PeriodKind    string  `json:"period_kind"`
	// ReadFrom: The filing the value is read from: the standing statement, or
	// under an as-of read the statement on file by that day; null where the
	// ledger holds no revision chain for the value yet. A derived figure names
	// the latest-filed of the statements its inputs are read from.
	ReadFrom *MetricStatementRef `json:"read_from"`
	// Revised: A later filing changed this figure (the revision chain holds a
	// revised statement). Under an as-of read, among the statements on file by
	// that day.
	Revised       *bool     `json:"revised"`
	RevisionCount *int64    `json:"revision_count"`
	StartDate     *Date     `json:"start_date"`
	Statement     *string   `json:"statement"`
	Ticker        *string   `json:"ticker"`
	Unit          string    `json:"unit"`
	Value         Decimal   `json:"value"`
	ValueKind     ValueKind `json:"value_kind"`
}

MetricValue: as the API sends it.

type MetricValuesEnvelope

type MetricValuesEnvelope struct {
	Data []MetricValue `json:"data"`
	Meta ResponseMeta  `json:"meta"`
}

MetricValuesEnvelope: as the API sends it.

type MetricsParams

type MetricsParams struct {
	// Period is which periods to read: the latest value of each metric by
	// default, annual, quarterly, or all.
	Period MetricPeriod
	// Keys is the metrics to read, every one when empty.
	Keys []string
	// Collapse folds each metric to one row per fiscal period.
	Collapse bool
	// Limit is at most this many rows.
	Limit int
	// AsOf reads the record as it stood on this day.
	AsOf Date
}

MetricsParams are the options of Client.Metrics.

type Number

type Number interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
		~float32 | ~float64 | Decimal | string
}

Number is what Where takes as a value: any integer or float, a Decimal, or a string already written as a plain decimal.

type Op

type Op string

Op is how a clause compares a column to its value.

const (
	// Gte is at least.
	Gte Op = "gte"
	// Lte is at most.
	Lte Op = "lte"
	// Gt is more than.
	Gt Op = "gt"
	// Lt is less than.
	Lt Op = "lt"
)

type Option

type Option func(*settings)

Option is a setting for New.

func WithAPIKey

func WithAPIKey(key string) Option

WithAPIKey is a key from https://thaler.sh/developers/keys; read from THALER_API_KEY when not given.

func WithBackoff

func WithBackoff(first time.Duration) Option

WithBackoff is the first pause before a retry of a 500, 502, 503, 504 or a failed connection; each retry doubles it, up to sixteen times, with jitter. Half a second by default.

func WithBaseURL

func WithBaseURL(baseURL string) Option

WithBaseURL is where the API lives; DefaultBaseURL by default.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient sends through an http.Client of your own, for a proxy or a custom transport. Its own timeout stands; WithTimeout is not applied to it.

func WithMaxConcurrent

func WithMaxConcurrent(count int) Option

WithMaxConcurrent is the requests kept in flight at once; four by default, which is what the API allows.

func WithMaxRetries

func WithMaxRetries(retries int) Option

WithMaxRetries is the tries after the first, on a 429 (waiting its Retry-After), a 500, 502, 503 or 504, or a failed connection; two by default.

func WithMaxRetryAfter

func WithMaxRetryAfter(wait time.Duration) Option

WithMaxRetryAfter is the longest the client waits for the API's limits: a Retry-After past it (the month's limit) is returned as an error at once, and a spent minute pauses the next request at most this long. A minute by default.

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout is how long to wait for an answer; thirty seconds by default.

type PriceAction

type PriceAction struct {
	// Evidence: The accession the filing's ratio came from
	Evidence *string         `json:"evidence"`
	ExDate   Date            `json:"ex_date"`
	Kind     PriceActionKind `json:"kind"`
	// Ratio: New shares per old share
	Ratio  *Decimal `json:"ratio"`
	Source string   `json:"source"`
}

PriceAction: as the API sends it.

type PriceActionKind

type PriceActionKind string

PriceActionKind: A corporate action on the price record.

const (
	PriceActionKindSplit        PriceActionKind = "split"
	PriceActionKindDividend     PriceActionKind = "dividend"
	PriceActionKindTickerChange PriceActionKind = "ticker_change"
)

type PriceLatest

type PriceLatest struct {
	Day        Date       `json:"day"`
	LastSaleAt *time.Time `json:"last_sale_at"`
	// MarketCap: price times shares; null when no count qualifies
	MarketCap    *Decimal `json:"market_cap"`
	Price        Decimal  `json:"price"`
	PriorDay     *Date    `json:"prior_day"`
	PriorPrice   *Decimal `json:"prior_price"`
	RecordClose  *Decimal `json:"record_close"`
	RecordDay    *Date    `json:"record_day"`
	RecordSource *string  `json:"record_source"`
	// Shares: The company's latest certified share count on or before the day, no
	// older than 400 days
	Shares     *Decimal `json:"shares"`
	SharesAsOf *Date    `json:"shares_as_of"`
	// Source: iex, or the record source that stands for the day
	Source    string    `json:"source"`
	Symbol    string    `json:"symbol"`
	UpdatedAt time.Time `json:"updated_at"`
}

PriceLatest: as the API sends it.

type PriceMark

type PriceMark struct {
	// Agreement: Share of the sample within one percent
	Agreement *Decimal `json:"agreement"`
	Close     Decimal  `json:"close"`
	Day       Date     `json:"day"`
	// Sample: Reports or trades behind the figure
	Sample int64  `json:"sample"`
	Source string `json:"source"`
}

PriceMark: as the API sends it.

type PriceRange

type PriceRange string

PriceRange: How far back to read prices.

const (
	PriceRangeOneMonth    PriceRange = "1m"
	PriceRangeThreeMonths PriceRange = "3m"
	PriceRangeOneYear     PriceRange = "1y"
	PriceRangeFiveYears   PriceRange = "5y"
	PriceRangeMax         PriceRange = "max"
)

type PriceSource

type PriceSource string

PriceSource: Where a day's price came from: IEX's last sale, or a close of record.

const (
	PriceSourceIEX         PriceSource = "iex"
	PriceSourceFails       PriceSource = "fails"
	PriceSourceIEXOfficial PriceSource = "iex_official"
	PriceSourceThirteenF   PriceSource = "thirteen_f"
	PriceSourceNport       PriceSource = "nport"
)

type Prices

type Prices struct {
	// Actions: Every split the company's filings and the tape agree on
	Actions []PriceAction `json:"actions"`
	// AdjPrice: The price in today's shares: divided by every split's ratio since
	// the day
	AdjPrice   []Decimal    `json:"adj_price"`
	CIK        int64        `json:"cik"`
	Days       []Date       `json:"days"`
	EntityName string       `json:"entity_name"`
	From       Date         `json:"from"`
	Latest     *PriceLatest `json:"latest"`
	// MarketCap: The price times the latest certified share count on or before
	// the day, carried through the splits between; null where no count within 400
	// days stands or the company's classes trade apart
	MarketCap []*Decimal  `json:"market_cap"`
	Marks     []PriceMark `json:"marks"`
	// Price: Dollars, as traded on the day
	Price  []Decimal     `json:"price"`
	Source []PriceSource `json:"source"`
	Ticker string        `json:"ticker"`
	To     Date          `json:"to"`
}

Prices: as the API sends it.

type PricesEnvelope

type PricesEnvelope struct {
	Data Prices       `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

PricesEnvelope: as the API sends it.

type PricesParams

type PricesParams struct {
	// Range is how far back: a month, three, a year, five, or all.
	Range PriceRange
	// From is the first day, instead of Range.
	From Date
	// To is the last day.
	To Date
}

PricesParams are the options of Client.Prices.

type Problem

type Problem struct {
	Code ProblemCode `json:"code"`
	// Detail: What went wrong and what to do, in a sentence or two.
	Detail string `json:"detail"`
	// RequestID: Quote it when you write to support@thaler.sh.
	RequestID string `json:"request_id"`
	Status    int64  `json:"status"`
	Title     string `json:"title"`
	Type      string `json:"type"`
	// ViolatedPolicies: On a 429, the limits the request would have broken.
	ViolatedPolicies []LimitPolicy `json:"violated-policies"`
}

Problem: An RFC 9457 problem. `type` links to the code's entry on the errors page.

type ProblemCode

type ProblemCode string

ProblemCode: What went wrong, as the errors page lists it.

const (
	ProblemCodeBadRequest       ProblemCode = "bad_request"
	ProblemCodeMissingKey       ProblemCode = "missing_key"
	ProblemCodeInvalidKey       ProblemCode = "invalid_key"
	ProblemCodeRevokedKey       ProblemCode = "revoked_key"
	ProblemCodeExpiredKey       ProblemCode = "expired_key"
	ProblemCodeNotFound         ProblemCode = "not_found"
	ProblemCodeMethodNotAllowed ProblemCode = "method_not_allowed"
	ProblemCodeRateLimited      ProblemCode = "rate_limited"
	ProblemCodeInternalError    ProblemCode = "internal_error"
	ProblemCodeUnavailable      ProblemCode = "unavailable"
	ProblemCodeTimeout          ProblemCode = "timeout"
)

type RateLimit

type RateLimit struct {
	// Minute is requests a minute.
	Minute *Window
	// Month is requests a month.
	Month *Window
	// Concurrent is requests at a time.
	Concurrent *Window
}

RateLimit is the account's limits as one answer reported them. A window the answer did not name is nil.

func ParseRateLimit

func ParseRateLimit(header http.Header) *RateLimit

ParseRateLimit reads the limits in an answer's headers, or nil when it carries none (an answer to a request without a valid key).

func (*RateLimit) Exhausted

func (r *RateLimit) Exhausted() []*Window

Exhausted lists the windows with nothing left, in the order the API lists them; none for a nil RateLimit.

type RawConcept

type RawConcept struct {
	CIK             int64  `json:"cik"`
	Concept         string `json:"concept"`
	EarliestEndDate *Date  `json:"earliest_end_date"`
	EntityName      string `json:"entity_name"`
	Exchange        string `json:"exchange"`
	FactCount       int64  `json:"fact_count"`
	LatestEndDate   *Date  `json:"latest_end_date"`
	Taxonomy        string `json:"taxonomy"`
	Ticker          string `json:"ticker"`
	Unit            string `json:"unit"`
}

RawConcept: as the API sends it.

type RawConceptsEnvelope

type RawConceptsEnvelope struct {
	Data []RawConcept `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

RawConceptsEnvelope: as the API sends it.

type RawConceptsParams

type RawConceptsParams struct {
	// Limit is at most this many rows.
	Limit int
}

RawConceptsParams are the options of Client.RawConcepts.

type Release

type Release struct {
	// Checks: Whether the release passed the checks run on it before it was
	// published.
	Checks ReleaseChecks `json:"checks"`
	// Date: The release date.
	Date        Date      `json:"date"`
	PublishedAt time.Time `json:"published_at"`
	// Stamp: The release date and the first characters of its content hash, which
	// identify it exactly.
	Stamp string `json:"stamp"`
}

Release: as the API sends it.

type ReleaseChecks

type ReleaseChecks string

ReleaseChecks: Whether a release passed the checks run before it was published.

const (
	ReleaseChecksPassed ReleaseChecks = "passed"
	ReleaseChecksFailed ReleaseChecks = "failed"
)

type ReleaseEnvelope

type ReleaseEnvelope struct {
	Data Release      `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

ReleaseEnvelope: as the API sends it.

type Response

type Response[T any] struct {
	// Data is the answer's data: a model, or a list of them.
	Data T
	// Meta is the answer's meta: the route, the parameters as the API read
	// them, the counts on the Screener, the release.
	Meta ResponseMeta
	// RequestID is the request's ID; quote it when writing to support.
	RequestID string
	// ETag is the answer's ETag.
	ETag string
	// RateLimit is the account's limits as this answer reported them.
	RateLimit *RateLimit
	// Header is the answer's headers.
	Header http.Header
}

Response is an answer from the API: its data, typed, and what rode along.

type ResponseMeta

type ResponseMeta struct {
	// AsOf: The day a read of the record as it stood was asked for.
	AsOf *Date `json:"as_of"`
	// Attribution: On prices, the attribution IEX's terms require wherever the
	// prices are shown.
	Attribution *Attribution `json:"attribution"`
	Collapse    *bool        `json:"collapse"`
	// Columns: On the Screener, the figures asked for with `columns`.
	Columns   []string       `json:"columns"`
	Date      *Date          `json:"date"`
	Dir       *SortDirection `json:"dir"`
	Forms     *string        `json:"forms"`
	Keys      []string       `json:"keys"`
	Kind      *TradeKind     `json:"kind"`
	Limit     *int64         `json:"limit"`
	MetricKey *string        `json:"metric_key"`
	Offset    *int64         `json:"offset"`
	Period    *MetricPeriod  `json:"period"`
	Query     *string        `json:"query"`
	// Release: The data release this response was served from; null before the
	// first release.
	Release *Release `json:"release"`
	// RequestID: Quote it when you write to support@thaler.sh.
	RequestID string   `json:"request_id"`
	Route     string   `json:"route"`
	Schema    string   `json:"schema"`
	SetAside  *int64   `json:"set_aside"`
	Since     *Date    `json:"since"`
	Sort      *string  `json:"sort"`
	Ticker    *string  `json:"ticker"`
	Total     *int64   `json:"total"`
	Universe  *int64   `json:"universe"`
	Where     []string `json:"where"`
}

ResponseMeta: as the API sends it.

type RevisionKind

type RevisionKind string

RevisionKind: A filing's statement of a figure against the statement before it: the first, the same figure, a revised one, or one re-expressed for a stock split.

const (
	RevisionKindFirst       RevisionKind = "first"
	RevisionKindSame        RevisionKind = "same"
	RevisionKindRevised     RevisionKind = "revised"
	RevisionKindReExpressed RevisionKind = "re_expressed"
)

type ScreenColumn

type ScreenColumn string

ScreenColumn: A figure the Screener can filter, sort and return.

const (
	ScreenColumnCoverageState               ScreenColumn = "coverage_state"
	ScreenColumnFiscalYear                  ScreenColumn = "fiscal_year"
	ScreenColumnAnnualEndDate               ScreenColumn = "annual_end_date"
	ScreenColumnInstantEndDate              ScreenColumn = "instant_end_date"
	ScreenColumnPriorAnnualEndDate          ScreenColumn = "prior_annual_end_date"
	ScreenColumnPublicFloatEndDate          ScreenColumn = "public_float_end_date"
	ScreenColumnSharesOutstandingEndDate    ScreenColumn = "shares_outstanding_end_date"
	ScreenColumnRevenue                     ScreenColumn = "revenue"
	ScreenColumnGrossProfit                 ScreenColumn = "gross_profit"
	ScreenColumnOperatingIncome             ScreenColumn = "operating_income"
	ScreenColumnNetIncome                   ScreenColumn = "net_income"
	ScreenColumnEPSDiluted                  ScreenColumn = "eps_diluted"
	ScreenColumnOperatingCashFlow           ScreenColumn = "operating_cash_flow"
	ScreenColumnCapitalExpenditures         ScreenColumn = "capital_expenditures"
	ScreenColumnFreeCashFlow                ScreenColumn = "free_cash_flow"
	ScreenColumnShareBasedCompensation      ScreenColumn = "share_based_compensation"
	ScreenColumnDepreciationAndAmortization ScreenColumn = "depreciation_and_amortization"
	ScreenColumnRevenuePrior                ScreenColumn = "revenue_prior"
	ScreenColumnNetIncomePrior              ScreenColumn = "net_income_prior"
	ScreenColumnAssets                      ScreenColumn = "assets"
	ScreenColumnCurrentAssets               ScreenColumn = "current_assets"
	ScreenColumnCashAndEquivalents          ScreenColumn = "cash_and_equivalents"
	ScreenColumnLiabilities                 ScreenColumn = "liabilities"
	ScreenColumnCurrentLiabilities          ScreenColumn = "current_liabilities"
	ScreenColumnStockholdersEquity          ScreenColumn = "stockholders_equity"
	ScreenColumnCommonSharesOutstanding     ScreenColumn = "common_shares_outstanding"
	ScreenColumnPublicFloat                 ScreenColumn = "public_float"
	ScreenColumnGrossMargin                 ScreenColumn = "gross_margin"
	ScreenColumnOperatingMargin             ScreenColumn = "operating_margin"
	ScreenColumnNetMargin                   ScreenColumn = "net_margin"
	ScreenColumnFCFMargin                   ScreenColumn = "fcf_margin"
	ScreenColumnROE                         ScreenColumn = "roe"
	ScreenColumnROA                         ScreenColumn = "roa"
	ScreenColumnCurrentRatio                ScreenColumn = "current_ratio"
	ScreenColumnCashRatio                   ScreenColumn = "cash_ratio"
	ScreenColumnLiabilitiesToEquity         ScreenColumn = "liabilities_to_equity"
	ScreenColumnRevenueYOY                  ScreenColumn = "revenue_yoy"
	ScreenColumnNetIncomeYOY                ScreenColumn = "net_income_yoy"
	ScreenColumnCapexIntensity              ScreenColumn = "capex_intensity"
	ScreenColumnSBCIntensity                ScreenColumn = "sbc_intensity"
	ScreenColumnDividendsPaid               ScreenColumn = "dividends_paid"
	ScreenColumnShareRepurchases            ScreenColumn = "share_repurchases"
	ScreenColumnDividendsPerShare           ScreenColumn = "dividends_per_share"
	ScreenColumnCapitalReturns              ScreenColumn = "capital_returns"
	ScreenColumnPayoutRatio                 ScreenColumn = "payout_ratio"
	ScreenColumnCapitalReturnsToFCF         ScreenColumn = "capital_returns_to_fcf"
	ScreenColumnSharesChange                ScreenColumn = "shares_change"
	ScreenColumnPrice                       ScreenColumn = "price"
	ScreenColumnPriceDay                    ScreenColumn = "price_day"
	ScreenColumnMarketCap                   ScreenColumn = "market_cap"
	ScreenColumnPE                          ScreenColumn = "pe"
	ScreenColumnPS                          ScreenColumn = "ps"
	ScreenColumnPB                          ScreenColumn = "pb"
	ScreenColumnFCFYield                    ScreenColumn = "fcf_yield"
	ScreenColumnDividendYield               ScreenColumn = "dividend_yield"
	ScreenColumnTTMEndDate                  ScreenColumn = "ttm_end_date"
	ScreenColumnRevenueTTM                  ScreenColumn = "revenue_ttm"
	ScreenColumnNetIncomeTTM                ScreenColumn = "net_income_ttm"
	ScreenColumnOperatingCashFlowTTM        ScreenColumn = "operating_cash_flow_ttm"
	ScreenColumnFreeCashFlowTTM             ScreenColumn = "free_cash_flow_ttm"
	ScreenColumnPETTM                       ScreenColumn = "pe_ttm"
	ScreenColumnPSTTM                       ScreenColumn = "ps_ttm"
	ScreenColumnFCFYieldTTM                 ScreenColumn = "fcf_yield_ttm"
)
const ScreenSortTicker ScreenColumn = "ticker"

ScreenSortTicker sorts the Screener by ticker, which is the default and not one of its figures.

type ScreenEnvelope

type ScreenEnvelope struct {
	Data []ScreenRow  `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

ScreenEnvelope: as the API sends it.

type ScreenParams

type ScreenParams struct {
	// Where is the clauses every row must pass; see [Where].
	Where []Clause
	// Sort is the column to sort by: a figure, or [ScreenSortTicker].
	Sort ScreenColumn
	// Dir is ascending by default.
	Dir SortDirection
	// Limit is at most this many rows, 25 by default and 500 at most.
	Limit int
	// Offset skips this many rows.
	Offset int
	// Columns is the figures to return in each row, beside its identity;
	// every figure when empty.
	Columns []ScreenColumn
}

ScreenParams are the options of Client.Screen.

type ScreenRow

type ScreenRow struct {
	AnnualEndDate               *Date    `json:"annual_end_date"`
	Assets                      *Decimal `json:"assets"`
	CapexIntensity              *Decimal `json:"capex_intensity"`
	CapitalExpenditures         *Decimal `json:"capital_expenditures"`
	CapitalReturns              *Decimal `json:"capital_returns"`
	CapitalReturnsToFCF         *Decimal `json:"capital_returns_to_fcf"`
	CashAndEquivalents          *Decimal `json:"cash_and_equivalents"`
	CashRatio                   *Decimal `json:"cash_ratio"`
	CIK                         int64    `json:"cik"`
	CommonSharesOutstanding     *Decimal `json:"common_shares_outstanding"`
	CoverageState               *string  `json:"coverage_state"`
	CurrentAssets               *Decimal `json:"current_assets"`
	CurrentLiabilities          *Decimal `json:"current_liabilities"`
	CurrentRatio                *Decimal `json:"current_ratio"`
	DepreciationAndAmortization *Decimal `json:"depreciation_and_amortization"`
	DividendYield               *Decimal `json:"dividend_yield"`
	DividendsPaid               *Decimal `json:"dividends_paid"`
	DividendsPerShare           *Decimal `json:"dividends_per_share"`
	EntityName                  string   `json:"entity_name"`
	EPSDiluted                  *Decimal `json:"eps_diluted"`
	Exchange                    string   `json:"exchange"`
	FCFMargin                   *Decimal `json:"fcf_margin"`
	FCFYield                    *Decimal `json:"fcf_yield"`
	FCFYieldTTM                 *Decimal `json:"fcf_yield_ttm"`
	FiscalYear                  *int64   `json:"fiscal_year"`
	FreeCashFlow                *Decimal `json:"free_cash_flow"`
	FreeCashFlowTTM             *Decimal `json:"free_cash_flow_ttm"`
	GrossMargin                 *Decimal `json:"gross_margin"`
	GrossProfit                 *Decimal `json:"gross_profit"`
	InstantEndDate              *Date    `json:"instant_end_date"`
	Liabilities                 *Decimal `json:"liabilities"`
	LiabilitiesToEquity         *Decimal `json:"liabilities_to_equity"`
	MarketCap                   *Decimal `json:"market_cap"`
	NetIncome                   *Decimal `json:"net_income"`
	NetIncomePrior              *Decimal `json:"net_income_prior"`
	NetIncomeTTM                *Decimal `json:"net_income_ttm"`
	NetIncomeYOY                *Decimal `json:"net_income_yoy"`
	NetMargin                   *Decimal `json:"net_margin"`
	OperatingCashFlow           *Decimal `json:"operating_cash_flow"`
	OperatingCashFlowTTM        *Decimal `json:"operating_cash_flow_ttm"`
	OperatingIncome             *Decimal `json:"operating_income"`
	OperatingMargin             *Decimal `json:"operating_margin"`
	PayoutRatio                 *Decimal `json:"payout_ratio"`
	PB                          *Decimal `json:"pb"`
	PE                          *Decimal `json:"pe"`
	PETTM                       *Decimal `json:"pe_ttm"`
	Price                       *Decimal `json:"price"`
	PriceDay                    *Date    `json:"price_day"`
	PriorAnnualEndDate          *Date    `json:"prior_annual_end_date"`
	PS                          *Decimal `json:"ps"`
	PSTTM                       *Decimal `json:"ps_ttm"`
	PublicFloat                 *Decimal `json:"public_float"`
	PublicFloatEndDate          *Date    `json:"public_float_end_date"`
	Revenue                     *Decimal `json:"revenue"`
	RevenuePrior                *Decimal `json:"revenue_prior"`
	RevenueTTM                  *Decimal `json:"revenue_ttm"`
	RevenueYOY                  *Decimal `json:"revenue_yoy"`
	ROA                         *Decimal `json:"roa"`
	ROE                         *Decimal `json:"roe"`
	SBCIntensity                *Decimal `json:"sbc_intensity"`
	ShareBasedCompensation      *Decimal `json:"share_based_compensation"`
	ShareRepurchases            *Decimal `json:"share_repurchases"`
	SharesChange                *Decimal `json:"shares_change"`
	SharesOutstandingEndDate    *Date    `json:"shares_outstanding_end_date"`
	StockholdersEquity          *Decimal `json:"stockholders_equity"`
	Ticker                      string   `json:"ticker"`
	TTMEndDate                  *Date    `json:"ttm_end_date"`
}

ScreenRow: as the API sends it.

type SearchHoldersParams

type SearchHoldersParams struct {
	// Query is a manager's name, or part of it; the largest managers
	// when empty.
	Query string
	// Limit is at most this many hits, 10 by default and 50 at most.
	Limit int
}

SearchHoldersParams are the options of Client.SearchHolders.

type SearchSecuritiesParams

type SearchSecuritiesParams struct {
	// Limit is at most this many hits, 25 by default and 500 at most.
	Limit int
}

SearchSecuritiesParams are the options of Client.SearchSecurities.

type SecurityHolder

type SecurityHolder struct {
	AccessionNumber string  `json:"accession_number"`
	Amount          Decimal `json:"amount"`
	// AmountType: SH for shares, PRN for principal amount.
	AmountType string `json:"amount_type"`
	FiledAt    Date   `json:"filed_at"`
	HolderCIK  int64  `json:"holder_cik"`
	HolderName string `json:"holder_name"`
	// PriorAmount: Null when the manager did not hold it a quarter earlier, or
	// when that quarter's report is not on file (see prior_known).
	PriorAmount *Decimal `json:"prior_amount"`
	// PriorKnown: Whether the manager's report for the quarter before is on file.
	PriorKnown bool     `json:"prior_known"`
	PriorValue *Decimal `json:"prior_value"`
	// Value: Dollars.
	Value Decimal `json:"value"`
	// Weight: Share of the manager's reported portfolio, as a fraction.
	Weight *Decimal `json:"weight"`
}

SecurityHolder: as the API sends it.

type SecurityHolders

type SecurityHolders struct {
	// AmountHeld: Shares held by the managers on file, as a decimal string.
	AmountHeld Decimal `json:"amount_held"`
	CIK        int64   `json:"cik"`
	// Closed: Managers who held it a quarter earlier and whose report now is on
	// file without it; null when no quarter before is on the ledger.
	Closed     *int64 `json:"closed"`
	EntityName string `json:"entity_name"`
	Holders    int64  `json:"holders"`
	// Opened: Managers holding it now whose report a quarter earlier is on file
	// without it; null when no quarter before is on the ledger.
	Opened *int64 `json:"opened"`
	// Period: The quarter end shown.
	Period          Date             `json:"period"`
	PriorAmountHeld *Decimal         `json:"prior_amount_held"`
	PriorHolders    *int64           `json:"prior_holders"`
	PriorPeriod     *Date            `json:"prior_period"`
	Rows            []SecurityHolder `json:"rows"`
	RowsTotal       int64            `json:"rows_total"`
	Ticker          string           `json:"ticker"`
	UpdatedAt       *time.Time       `json:"updated_at"`
	// ValueHeld: Dollars.
	ValueHeld Decimal `json:"value_held"`
}

SecurityHolders: as the API sends it.

type SecurityHoldersEnvelope

type SecurityHoldersEnvelope struct {
	Data SecurityHolders `json:"data"`
	Meta ResponseMeta    `json:"meta"`
}

SecurityHoldersEnvelope: as the API sends it.

type SecurityProfile

type SecurityProfile struct {
	CIK                  int64  `json:"cik"`
	CompanyCoverageState string `json:"company_coverage_state"`
	EntityName           string `json:"entity_name"`
	Exchange             string `json:"exchange"`
	FilingCount          int64  `json:"filing_count"`
	IsActive             bool   `json:"is_active"`
	IsPrimary            bool   `json:"is_primary"`
	LatestFilingAt       *Date  `json:"latest_filing_at"`
	MetricValueCount     int64  `json:"metric_value_count"`
	// Price: The latest price and market cap on the ledger, absent when there is
	// none
	Price                 *PriceLatest `json:"price"`
	RawFactCount          int64        `json:"raw_fact_count"`
	SecurityCoverageState string       `json:"security_coverage_state"`
	SecurityID            string       `json:"security_id"`
	Ticker                string       `json:"ticker"`
	TickerNormalized      string       `json:"ticker_normalized"`
}

SecurityProfile: as the API sends it.

type SecurityProfileEnvelope

type SecurityProfileEnvelope struct {
	Data SecurityProfile `json:"data"`
	Meta ResponseMeta    `json:"meta"`
}

SecurityProfileEnvelope: as the API sends it.

type SecuritySearchEnvelope

type SecuritySearchEnvelope struct {
	Data []SecuritySearchHit `json:"data"`
	Meta ResponseMeta        `json:"meta"`
}

SecuritySearchEnvelope: as the API sends it.

type SecuritySearchHit

type SecuritySearchHit struct {
	CIK                   int64  `json:"cik"`
	CompanyCoverageState  string `json:"company_coverage_state"`
	EntityName            string `json:"entity_name"`
	Exchange              string `json:"exchange"`
	SecurityCoverageState string `json:"security_coverage_state"`
	Ticker                string `json:"ticker"`
	TickerNormalized      string `json:"ticker_normalized"`
}

SecuritySearchHit: as the API sends it.

type SegmentAxis

type SegmentAxis struct {
	Axis     Axis             `json:"axis"`
	Measures []SegmentMeasure `json:"measures"`
}

SegmentAxis: as the API sends it.

type SegmentMeasure

type SegmentMeasure struct {
	// Concept: The XBRL concept as filed, `us-gaap:OperatingIncomeLoss`.
	Concept string          `json:"concept"`
	Measure Measure         `json:"measure"`
	Members []SegmentMember `json:"members"`
	Periods []SegmentPeriod `json:"periods"`
	// Totals: The consolidated figure per period, as a decimal string.
	Totals []*Decimal `json:"totals"`
	Unit   string     `json:"unit"`
}

SegmentMeasure: as the API sends it.

type SegmentMember

type SegmentMember struct {
	Label string `json:"label"`
	// Member: The member as filed, `aapl:IPhoneMember`.
	Member string `json:"member"`
	// Values: One figure per period, in the periods' order, as decimal strings.
	Values []*Decimal `json:"values"`
}

SegmentMember: as the API sends it.

type SegmentPeriod

type SegmentPeriod struct {
	AccessionNumber string `json:"accession_number"`
	// Derived: Present and true when the period is a fourth quarter taken as the
	// year less three quarters.
	Derived      *bool  `json:"derived"`
	EndDate      Date   `json:"end_date"`
	FiledAt      *Date  `json:"filed_at"`
	FiscalPeriod string `json:"fiscal_period"`
	FiscalYear   int64  `json:"fiscal_year"`
	Form         string `json:"form"`
}

SegmentPeriod: as the API sends it.

type Segments

type Segments struct {
	Axes []SegmentAxis `json:"axes"`
	CIK  int64         `json:"cik"`
	// Documents: Reports read for this company.
	Documents  int64          `json:"documents"`
	EntityName string         `json:"entity_name"`
	Period     SegmentsPeriod `json:"period"`
	Ticker     string         `json:"ticker"`
	UpdatedAt  *time.Time     `json:"updated_at"`
}

Segments: as the API sends it.

type SegmentsEnvelope

type SegmentsEnvelope struct {
	Data Segments     `json:"data"`
	Meta ResponseMeta `json:"meta"`
}

SegmentsEnvelope: as the API sends it.

type SegmentsParams

type SegmentsParams struct {
	// Period is annual by default, or quarterly.
	Period SegmentsPeriod
}

SegmentsParams are the options of Client.Segments.

type SegmentsPeriod

type SegmentsPeriod string

SegmentsPeriod: Annual figures, or quarterly with a derived fourth quarter.

const (
	SegmentsPeriodAnnual    SegmentsPeriod = "annual"
	SegmentsPeriodQuarterly SegmentsPeriod = "quarterly"
)

type SortDirection

type SortDirection string

SortDirection: Ascending or descending.

const (
	SortDirectionAsc  SortDirection = "asc"
	SortDirectionDesc SortDirection = "desc"
)

type TradeKind

type TradeKind string

TradeKind: An open-market purchase or sale.

const (
	TradeKindPurchase TradeKind = "purchase"
	TradeKindSale     TradeKind = "sale"
)

type TransactionCode

type TransactionCode string

TransactionCode: The SEC transaction code: P for an open-market purchase, S for a sale.

const (
	TransactionCodePurchase TransactionCode = "P"
	TransactionCodeSale     TransactionCode = "S"
)

type TransportError

type TransportError struct {
	// Operation is the API operation that was asked for, as the OpenAPI
	// document names it.
	Operation string
	// Err is what the transport reported.
	Err error
}

TransportError means the request got no answer: a connection failed or timed out, after the retries, or the context ended. Err is the cause, so errors.Is(err, context.DeadlineExceeded) still tells.

func (*TransportError) Error

func (e *TransportError) Error() string

Error names the operation and the cause.

func (*TransportError) Unwrap

func (e *TransportError) Unwrap() error

Unwrap is the cause.

type ValueKind

type ValueKind string

ValueKind: Whether a value was reported in a filing or derived by Thaler from reported values.

const (
	ValueKindReported ValueKind = "reported"
	ValueKindDerived  ValueKind = "derived"
)

type ValueStatus

type ValueStatus string

ValueStatus: Whether a transaction's value counts in the totals.

const (
	ValueStatusCounted   ValueStatus = "counted"
	ValueStatusSuspect   ValueStatus = "suspect"
	ValueStatusNotEquity ValueStatus = "not_equity"
)

type Window

type Window struct {
	// Name is minute, month or concurrent.
	Name string
	// Limit is the requests the policy allows; -1 when the policy was not
	// reported.
	Limit int64
	// Remaining is the requests left; -1 when not reported.
	Remaining int64
	// Reset is the time until the count resets; zero when not reported,
	// as the concurrent limit has none.
	Reset time.Duration
}

Window is one limit: what it allows, what remains, and when it resets.

The API carries the IETF RateLimit header fields on every answer to a request with a valid key:

ratelimit-policy: "minute";q=60;w=60, "month";q=20000, "concurrent";q=4;qu="concurrent-requests"
ratelimit: "minute";r=59;t=42, "month";r=19873;t=536400, "concurrent";r=3

q is the limit and w its window in seconds; r is what remains and t the seconds until the count resets.

Jump to

Keyboard shortcuts

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