Skip to content

Commit

Permalink
Added GetShortInterest and ListIPOs support
Browse files Browse the repository at this point in the history
  • Loading branch information
justinpolygon committed Oct 9, 2024
1 parent 4518350 commit b65b919
Show file tree
Hide file tree
Showing 6 changed files with 359 additions and 1 deletion.
2 changes: 1 addition & 1 deletion rest/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/polygon-io/client-go/rest/models"
)

const clientVersion = "v1.16.0"
const clientVersion = "v1.16.7"

const (
APIURL = "https://api.polygon.io"
Expand Down
36 changes: 36 additions & 0 deletions rest/example/stocks/company-ipos/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Stocks - Company IPOs
// https://polygon.io/docs/stocks/get_v1_reference_ipos
package main

import (
"context"
"log"
"os"

polygon "github.com/polygon-io/client-go/rest"
"github.com/polygon-io/client-go/rest/models"
)

func main() {

// Initialize client
c := polygon.New(os.Getenv("POLYGON_API_KEY"))

// Set parameters (optional)
params := models.ListIPOsParams{}.
WithLimit(1).
WithOrder(models.Asc).
WithSort(models.IPOsSortListingDate)

// make request
iter := c.ListIPOs(context.Background(), params)

// do something with the result
for iter.Next() {
log.Print(iter.Item())
}
if iter.Err() != nil {
log.Fatal(iter.Err())
}

}
33 changes: 33 additions & 0 deletions rest/example/stocks/short-interest/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Stocks - Short Interest
// https://polygon.io/docs/stocks/get_v1_reference_short-interest__identifierType___identifier
package main

import (
"context"
"log"
"os"

polygon "github.com/polygon-io/client-go/rest"
"github.com/polygon-io/client-go/rest/models"
)

func main() {

// Initialize client
c := polygon.New(os.Getenv("POLYGON_API_KEY"))

// Set parameters
params := models.GetShortInterestParams{
IdentifierType: "ticker",
Identifier: "AAPL",
}

// Make request
res, err := c.GetShortInterest(context.Background(), &params)
if err != nil {
log.Fatal(err)
}

// Handle the result
log.Print(res)
}
161 changes: 161 additions & 0 deletions rest/models/tickers.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,3 +420,164 @@ type TickerEvent struct {
type TickerChangeEvent struct {
Ticker string `json:"ticker"`
}

// GetShortInterestParams contains parameters for the GetShortInterest method.
type GetShortInterestParams struct {
// Path parameters
IdentifierType string `validate:"required" path:"identifierType"`
Identifier string `validate:"required" path:"identifier"`

// Query parameters
Date *string `query:"date,omitempty"`
Order *string `query:"order,omitempty"`
Limit *int `query:"limit,omitempty"`
Sort *string `query:"sort,omitempty"`
}

// WithDate sets the optional Date parameter.
func (p GetShortInterestParams) WithDate(date string) *GetShortInterestParams {
p.Date = &date
return &p
}

// WithOrder sets the optional Order parameter.
func (p GetShortInterestParams) WithOrder(order string) *GetShortInterestParams {
p.Order = &order
return &p
}

// WithLimit sets the optional Limit parameter.
func (p GetShortInterestParams) WithLimit(limit int) *GetShortInterestParams {
p.Limit = &limit
return &p
}

// WithSort sets the optional Sort parameter.
func (p GetShortInterestParams) WithSort(sort string) *GetShortInterestParams {
p.Sort = &sort
return &p
}

// GetShortInterestResponse represents the response from the GetShortInterest method.
type GetShortInterestResponse struct {
BaseResponse

NextURL string `json:"next_url,omitempty"`
RequestID string `json:"request_id,omitempty"`
Results []ShortInterest `json:"results,omitempty"`
Status string `json:"status,omitempty"`
}

// ShortInterest represents a single short interest data point.
type ShortInterest struct {
CurrencyCode string `json:"currency_code,omitempty"`
Date string `json:"date,omitempty"`
ISIN string `json:"isin,omitempty"`
Name string `json:"name,omitempty"`
SecurityDescription string `json:"security_description,omitempty"`
ShortVolume int64 `json:"short_volume,omitempty"`
ShortVolumeExempt int64 `json:"short_volume_exempt,omitempty"`
Ticker string `json:"ticker,omitempty"`
USCode string `json:"us_code,omitempty"`
}

// IPOsSortField defines the sort fields for IPOs.
type IPOsSortField string

const (
IPOsSortTicker IPOsSortField = "ticker"
IPOsSortListingDate IPOsSortField = "listing_date"
IPOsSortUsCode IPOsSortField = "us_code"
IPOsSortIsin IPOsSortField = "isin"
IPOsSortIssueEndDate IPOsSortField = "issue_end_date"
)

// ListIPOsParams contains parameters for the ListIPOs method.
type ListIPOsParams struct {
// Query parameters
Ticker *string `query:"ticker,omitempty"`
USCode *string `query:"us_code,omitempty"`
ISIN *string `query:"isin,omitempty"`
ListingDate *string `query:"listing_date,omitempty"`
Order *Order `query:"order,omitempty"`
Limit *int `query:"limit,omitempty"`
Sort *IPOsSortField `query:"sort,omitempty"`
}

// WithTicker sets the Ticker parameter.
func (p ListIPOsParams) WithTicker(ticker string) *ListIPOsParams {
p.Ticker = &ticker
return &p
}

// WithUSCode sets the USCode parameter.
func (p ListIPOsParams) WithUSCode(usCode string) *ListIPOsParams {
p.USCode = &usCode
return &p
}

// WithISIN sets the ISIN parameter.
func (p ListIPOsParams) WithISIN(isin string) *ListIPOsParams {
p.ISIN = &isin
return &p
}

// WithListingDate sets the ListingDate parameter.
func (p ListIPOsParams) WithListingDate(listingDate string) *ListIPOsParams {
p.ListingDate = &listingDate
return &p
}

// WithOrder sets the Order parameter.
func (p ListIPOsParams) WithOrder(order Order) *ListIPOsParams {
p.Order = &order
return &p
}

// WithLimit sets the Limit parameter.
func (p ListIPOsParams) WithLimit(limit int) *ListIPOsParams {
p.Limit = &limit
return &p
}

// WithSort sets the Sort parameter.
func (p ListIPOsParams) WithSort(sort IPOsSortField) *ListIPOsParams {
p.Sort = &sort
return &p
}

// ListIPOsResponse represents the response from the ListIPOs method.
type ListIPOsResponse struct {
BaseResponse

NextURL string `json:"next_url,omitempty"`
RequestID string `json:"request_id,omitempty"`
Results []IPOListing `json:"results,omitempty"`
Status string `json:"status,omitempty"`
}

// IPOListing represents a single IPO listing.
type IPOListing struct {
CurrencyCode string `json:"currency_code,omitempty"`
FinalIssuePrice float64 `json:"final_issue_price,omitempty"`
HighestOfferPrice float64 `json:"highest_offer_price,omitempty"`
IPOStatus string `json:"ipo_status,omitempty"`
ISIN string `json:"isin,omitempty"`
IssueEndDate string `json:"issue_end_date,omitempty"`
IssueStartDate string `json:"issue_start_date,omitempty"`
IssuerName string `json:"issuer_name,omitempty"`
LastUpdated string `json:"last_updated,omitempty"`
ListingDate string `json:"listing_date,omitempty"`
ListingPrice float64 `json:"listing_price,omitempty"`
LotSize int64 `json:"lot_size,omitempty"`
LowestOfferPrice float64 `json:"lowest_offer_price,omitempty"`
MaxSharesOffered int64 `json:"max_shares_offered,omitempty"`
MinSharesOffered int64 `json:"min_shares_offered,omitempty"`
PrimaryExchange string `json:"primary_exchange,omitempty"`
SecurityDescription string `json:"security_description,omitempty"`
SecurityType string `json:"security_type,omitempty"`
SharesOutstanding int64 `json:"shares_outstanding,omitempty"`
Ticker string `json:"ticker,omitempty"`
TotalOfferSize float64 `json:"total_offer_size,omitempty"`
USCode string `json:"us_code,omitempty"`
}
22 changes: 22 additions & 0 deletions rest/reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ const (
GetTickerRelatedCompaniesPath = "/v1/related-companies/{ticker}"
GetTickerTypesPath = "/v3/reference/tickers/types"

GetShortInterestPath = "/v1/reference/short-interest/{identifierType}/{identifier}"

ListIPOsPath = "/v1/reference/ipos"

GetMarketHolidaysPath = "/v1/marketstatus/upcoming"
GetMarketStatusPath = "/v1/marketstatus/now"

Expand Down Expand Up @@ -210,3 +214,21 @@ func (c *ReferenceClient) ListOptionsContracts(ctx context.Context, params *mode
return res, res.Results, err
})
}

// GetShortInterest retrieves short interest data for a given identifier and date.
// For more details, see: https://polygon.io/docs/stocks/get_v1_reference_short-interest__identifiertype___identifier
func (c *ReferenceClient) GetShortInterest(ctx context.Context, params *models.GetShortInterestParams, options ...models.RequestOption) (*models.GetShortInterestResponse, error) {
res := &models.GetShortInterestResponse{}
err := c.Call(ctx, http.MethodGet, GetShortInterestPath, params, res, options...)
return res, err
}

// ListIPOs retrieves a list of upcoming or historical IPOs.
// For more details, see: https://polygon.io/docs/stocks/get_v1_reference_ipos
func (c *ReferenceClient) ListIPOs(ctx context.Context, params *models.ListIPOsParams, options ...models.RequestOption) *iter.Iter[models.IPOListing] {
return iter.NewIter(ctx, ListIPOsPath, params, func(uri string) (iter.ListResponse, []models.IPOListing, error) {
res := &models.ListIPOsResponse{}
err := c.CallURL(ctx, http.MethodGet, uri, res, options...)
return res, res.Results, err
})
}
106 changes: 106 additions & 0 deletions rest/reference_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,3 +683,109 @@ func TestListOptionsContracts(t *testing.T) {
assert.False(t, iter.Next())
assert.Nil(t, iter.Err())
}

func TestGetShortInterest(t *testing.T) {
c := polygon.New("API_KEY")

httpmock.ActivateNonDefault(c.HTTP.GetClient())
defer httpmock.DeactivateAndReset()

expectedResponse := `{
"results": [{
"currency_code": "USD",
"date": "2023-12-31",
"isin": "US0378331005",
"name": "Apple Inc.",
"security_description": "Common Stock",
"short_volume": 2006566,
"short_volume_exempt": 3000,
"ticker": "AAPL",
"us_code": "378331005"
}],
"status": "OK",
"request_id": "some-request-id",
"next_url": null
}`

// Mock the API response
registerResponder("https://api.polygon.io/v1/reference/short-interest/ticker/AAPL", expectedResponse)

params := models.GetShortInterestParams{
IdentifierType: "ticker",
Identifier: "AAPL",
}
res, err := c.GetShortInterest(context.Background(), &params)
assert.Nil(t, err)

var expect models.GetShortInterestResponse
err = json.Unmarshal([]byte(expectedResponse), &expect)
assert.Nil(t, err)
assert.Equal(t, &expect, res)
}

func TestListIPOs(t *testing.T) {
c := polygon.New("API_KEY")

httpmock.ActivateNonDefault(c.HTTP.GetClient())
defer httpmock.DeactivateAndReset()

ipo1 := `{
"currency_code": "USD",
"final_issue_price": 17,
"highest_offer_price": 17,
"ipo_status": "HISTORY",
"isin": "US75383L1026",
"issue_end_date": "2024-06-06",
"issue_start_date": "2024-06-01",
"issuer_name": "Rapport Therapeutics Inc.",
"last_updated": "2024-06-27",
"listing_date": "2024-06-07",
"listing_price": null,
"lot_size": 100,
"lowest_offer_price": 17,
"max_shares_offered": 8000000,
"min_shares_offered": 1000000,
"primary_exchange": "XNAS",
"security_description": "Ordinary Shares",
"security_type": "CS",
"shares_outstanding": 35376457,
"ticker": "RAPP",
"total_offer_size": 136000000,
"us_code": "75383L102"
}`

// Construct the expected API response with the IPO listing
expectedResponse := `{
"status": "OK",
"count": 1,
"next_url": "https://api.polygon.io/v1/reference/ipos?cursor=nextCursorValue",
"request_id": "6a7e466379af0a71039d60cc78e72282",
"results": [
` + indent(true, ipo1, "\t\t") + `
]
}`

registerResponder("https://api.polygon.io/v1/reference/ipos?limit=10&order=asc&sort=listing_date", expectedResponse)
registerResponder("https://api.polygon.io/v1/reference/ipos?cursor=nextCursorValue", "{}")

iter := c.ListIPOs(context.Background(), models.ListIPOsParams{}.
WithLimit(10).
WithOrder(models.Asc).
WithSort(models.IPOsSortListingDate))

// iter creation
assert.Nil(t, iter.Err())
assert.NotNil(t, iter.Item())

// first item
assert.True(t, iter.Next())
assert.Nil(t, iter.Err())
var expect models.IPOListing
err := json.Unmarshal([]byte(ipo1), &expect)
assert.Nil(t, err)
assert.Equal(t, expect, iter.Item())

// end of list
assert.False(t, iter.Next())
assert.Nil(t, iter.Err())
}

0 comments on commit b65b919

Please sign in to comment.