diff --git a/rest/futures.go b/rest/futures.go new file mode 100644 index 00000000..5853315c --- /dev/null +++ b/rest/futures.go @@ -0,0 +1,113 @@ +package polygon + +import ( + "context" + "github.com/polygon-io/client-go/rest/client" + "github.com/polygon-io/client-go/rest/iter" + "github.com/polygon-io/client-go/rest/models" + "net/http" +) + +const ( + ListFuturesAggsPath = "/futures/vX/aggs/{ticker}" + ListFuturesContractsPath = "/futures/vX/contracts" + GetFuturesContractPath = "/futures/vX/contracts/{ticker}" + ListFuturesMarketStatusesPath = "/futures/vX/market-status" + ListFuturesProductsPath = "/futures/vX/products" + GetFuturesProductPath = "/futures/vX/products/{product_code}" + ListFuturesSchedulesPath = "/futures/vX/schedules" + ListFuturesProductSchedulesPath = "/futures/vX/products/{product_code}/schedules" + ListFuturesTradesPath = "/futures/vX/trades/{ticker}" + ListFuturesQuotesPath = "/futures/vX/quotes/{ticker}" +) + +// FuturesClient provides methods for interacting with the futures REST API. +type FuturesClient struct { + client.Client +} + +// ListFuturesAggs retrieves a list of aggregates for a futures contract. +func (fc *FuturesClient) ListFuturesAggs(ctx context.Context, params *models.ListFuturesAggsParams, options ...models.RequestOption) *iter.Iter[models.FuturesAggregate] { + return iter.NewIter(ctx, ListFuturesAggsPath, params, func(uri string) (iter.ListResponse, []models.FuturesAggregate, error) { + res := &models.ListFuturesAggsResponse{} + err := fc.CallURL(ctx, http.MethodGet, uri, res, options...) + return res, res.Results, err + }) +} + +// ListFuturesContracts retrieves a list of futures contracts. +func (fc *FuturesClient) ListFuturesContracts(ctx context.Context, params *models.ListFuturesContractsParams, options ...models.RequestOption) *iter.Iter[models.FuturesContract] { + return iter.NewIter(ctx, ListFuturesContractsPath, params, func(uri string) (iter.ListResponse, []models.FuturesContract, error) { + res := &models.ListFuturesContractsResponse{} + err := fc.CallURL(ctx, http.MethodGet, uri, res, options...) + return res, res.Results, err + }) +} + +// GetFuturesContract retrieves details for a specific futures contract. +func (fc *FuturesClient) GetFuturesContract(ctx context.Context, params *models.GetFuturesContractParams, options ...models.RequestOption) (*models.GetFuturesContractResponse, error) { + res := &models.GetFuturesContractResponse{} + err := fc.Call(ctx, http.MethodGet, GetFuturesContractPath, params, res, options...) + return res, err +} + +// ListFuturesMarketStatuses retrieves market statuses for futures products. +func (fc *FuturesClient) ListFuturesMarketStatuses(ctx context.Context, params *models.ListFuturesMarketStatusesParams, options ...models.RequestOption) *iter.Iter[models.FuturesMarketStatus] { + return iter.NewIter(ctx, ListFuturesMarketStatusesPath, params, func(uri string) (iter.ListResponse, []models.FuturesMarketStatus, error) { + res := &models.ListFuturesMarketStatusesResponse{} + err := fc.CallURL(ctx, http.MethodGet, uri, res, options...) + return res, res.Results, err + }) +} + +// ListFuturesProducts retrieves a list of futures products. +func (fc *FuturesClient) ListFuturesProducts(ctx context.Context, params *models.ListFuturesProductsParams, options ...models.RequestOption) *iter.Iter[models.FuturesProduct] { + return iter.NewIter(ctx, ListFuturesProductsPath, params, func(uri string) (iter.ListResponse, []models.FuturesProduct, error) { + res := &models.ListFuturesProductsResponse{} + err := fc.CallURL(ctx, http.MethodGet, uri, res, options...) + return res, res.Results, err + }) +} + +// GetFuturesProduct retrieves details for a specific futures product. +func (fc *FuturesClient) GetFuturesProduct(ctx context.Context, params *models.GetFuturesProductParams, options ...models.RequestOption) (*models.GetFuturesProductResponse, error) { + res := &models.GetFuturesProductResponse{} + err := fc.Call(ctx, http.MethodGet, GetFuturesProductPath, params, res, options...) + return res, err +} + +// ListFuturesSchedules retrieves trading schedules for futures. +func (fc *FuturesClient) ListFuturesSchedules(ctx context.Context, params *models.ListFuturesSchedulesParams, options ...models.RequestOption) *iter.Iter[models.FuturesSchedule] { + return iter.NewIter(ctx, ListFuturesSchedulesPath, params, func(uri string) (iter.ListResponse, []models.FuturesSchedule, error) { + res := &models.ListFuturesSchedulesResponse{} + err := fc.CallURL(ctx, http.MethodGet, uri, res, options...) + return res, res.Results, err + }) +} + +// ListFuturesProductSchedules retrieves trading schedules for a specific futures product. +func (fc *FuturesClient) ListFuturesProductSchedules(ctx context.Context, params *models.ListFuturesProductSchedulesParams, options ...models.RequestOption) *iter.Iter[models.FuturesSchedule] { + return iter.NewIter(ctx, ListFuturesProductSchedulesPath, params, func(uri string) (iter.ListResponse, []models.FuturesSchedule, error) { + res := &models.ListFuturesProductSchedulesResponse{} + err := fc.CallURL(ctx, http.MethodGet, uri, res, options...) + return res, res.Results, err + }) +} + +// ListFuturesTrades retrieves a list of trades for a futures contract. +func (fc *FuturesClient) ListFuturesTrades(ctx context.Context, params *models.ListFuturesTradesParams, options ...models.RequestOption) *iter.Iter[models.FuturesTrade] { + return iter.NewIter(ctx, ListFuturesTradesPath, params, func(uri string) (iter.ListResponse, []models.FuturesTrade, error) { + res := &models.ListFuturesTradesResponse{} + err := fc.CallURL(ctx, http.MethodGet, uri, res, options...) + return res, res.Results, err + }) +} + +// ListFuturesQuotes retrieves a list of quotes for a futures contract. +func (fc *FuturesClient) ListFuturesQuotes(ctx context.Context, params *models.ListFuturesQuotesParams, options ...models.RequestOption) *iter.Iter[models.FuturesQuote] { + return iter.NewIter(ctx, ListFuturesQuotesPath, params, func(uri string) (iter.ListResponse, []models.FuturesQuote, error) { + res := &models.ListFuturesQuotesResponse{} + err := fc.CallURL(ctx, http.MethodGet, uri, res, options...) + return res, res.Results, err + }) +} diff --git a/rest/models/futures.go b/rest/models/futures.go new file mode 100644 index 00000000..fe1cfcad --- /dev/null +++ b/rest/models/futures.go @@ -0,0 +1,248 @@ +package models + +import ( + "time" +) + +// ListFuturesAggsParams defines parameters for listing futures aggregates. +type ListFuturesAggsParams struct { + Ticker string `validate:"required" path:"ticker"` + Resolution string `validate:"required" query:"resolution"` + WindowStart *Nanos `query:"window_start"` + WindowStartGT *Nanos `query:"window_start.gt"` + WindowStartGTE *Nanos `query:"window_start.gte"` + WindowStartLT *Nanos `query:"window_start.lt"` + WindowStartLTE *Nanos `query:"window_start.lte"` + Order *Order `query:"order"` + Limit *int `query:"limit"` + Sort *Sort `query:"sort"` +} + +// ListFuturesContractsParams defines parameters for listing futures contracts. +type ListFuturesContractsParams struct { + ProductCode *string `query:"product_code"` + FirstTradeDate *Date `query:"first_trade_date"` + LastTradeDate *Date `query:"last_trade_date"` + ExpirationDate *Date `query:"expiration_date"` + Active *string `query:"active"` + Type *string `query:"type"` + Order *Order `query:"order"` + Limit *int `query:"limit"` + Sort *Sort `query:"sort"` +} + +// GetFuturesContractParams defines parameters for retrieving a specific futures contract. +type GetFuturesContractParams struct { + Ticker string `validate:"required" path:"ticker"` + AsOf *Date `query:"as_of"` +} + +// ListFuturesMarketStatusesParams defines parameters for listing market statuses. +type ListFuturesMarketStatusesParams struct { + ProductCode *string `query:"product_code"` + ExchangeCode *string `query:"exchange_code"` + Order *Order `query:"order"` + Limit *int `query:"limit"` + Sort *Sort `query:"sort"` +} + +// ListFuturesProductsParams defines parameters for listing futures products. +type ListFuturesProductsParams struct { + Name *string `query:"name"` + AssetClass *string `query:"asset_class"` + ExchangeCode *string `query:"exchange_code"` + Sector *string `query:"sector"` + SubSector *string `query:"sub_sector"` + Type *string `query:"type"` + Order *Order `query:"order"` + Limit *int `query:"limit"` + Sort *Sort `query:"sort"` +} + +// GetFuturesProductParams defines parameters for retrieving a specific futures product. +type GetFuturesProductParams struct { + ProductCode string `validate:"required" path:"product_code"` + AsOf *Date `query:"as_of"` +} + +// ListFuturesSchedulesParams defines parameters for listing futures schedules. +type ListFuturesSchedulesParams struct { + SessionStartDate *Date `query:"session_start_date"` + MarketIdentifierCode *string `query:"market_identifier_code"` + Order *Order `query:"order"` + Limit *int `query:"limit"` + Sort *Sort `query:"sort"` +} + +// ListFuturesProductSchedulesParams defines parameters for listing schedules for a specific product. +type ListFuturesProductSchedulesParams struct { + ProductCode string `validate:"required" path:"product_code"` + SessionEndDate *Date `query:"session_end_date"` + SessionEndDateGT *Date `query:"session_end_date.gt"` + SessionEndDateGTE *Date `query:"session_end_date.gte"` + SessionEndDateLT *Date `query:"session_end_date.lt"` + SessionEndDateLTE *Date `query:"session_end_date.lte"` + Order *Order `query:"order"` + Limit *int `query:"limit"` +} + +// ListFuturesTradesParams defines parameters for listing futures trades. +type ListFuturesTradesParams struct { + Ticker string `validate:"required" path:"ticker"` + Timestamp *Nanos `query:"timestamp"` + TimestampGT *Nanos `query:"timestamp.gt"` + TimestampGTE *Nanos `query:"timestamp.gte"` + TimestampLT *Nanos `query:"timestamp.lt"` + TimestampLTE *Nanos `query:"timestamp.lte"` + Order *Order `query:"order"` + Limit *int `query:"limit"` + Sort *Sort `query:"sort"` +} + +// ListFuturesQuotesParams defines parameters for listing futures quotes. +type ListFuturesQuotesParams struct { + Ticker string `validate:"required" path:"ticker"` + Timestamp *Nanos `query:"timestamp"` + TimestampGT *Nanos `query:"timestamp.gt"` + TimestampGTE *Nanos `query:"timestamp.gte"` + TimestampLT *Nanos `query:"timestamp.lt"` + TimestampLTE *Nanos `query:"timestamp.lte"` + Order *Order `query:"order"` + Limit *int `query:"limit"` + Sort *Sort `query:"sort"` +} + +// FuturesAggregate represents a single aggregate bar for futures. +type FuturesAggregate struct { + Ticker string `json:"ticker"` + Open float64 `json:"open"` + High float64 `json:"high"` + Low float64 `json:"low"` + Close float64 `json:"close"` + Volume int64 `json:"volume"` + WindowStart int64 `json:"window_start"` + WindowEnd int64 `json:"window_end"` +} + +// ListFuturesAggsResponse defines the response for listing futures aggregates. +type ListFuturesAggsResponse struct { + BaseResponse + Results []FuturesAggregate `json:"results,omitempty"` +} + +// FuturesContract represents a futures contract. +type FuturesContract struct { + Ticker string `json:"ticker"` + ProductCode string `json:"product_code"` + ExpirationDate Date `json:"expiration_date"` + FirstTradeDate Date `json:"first_trade_date"` + LastTradeDate Date `json:"last_trade_date"` + Active bool `json:"active"` + Type string `json:"type"` +} + +// ListFuturesContractsResponse defines the response for listing futures contracts. +type ListFuturesContractsResponse struct { + BaseResponse + Results []FuturesContract `json:"results,omitempty"` +} + +// GetFuturesContractResponse defines the response for retrieving a specific futures contract. +type GetFuturesContractResponse struct { + BaseResponse + Result FuturesContract `json:"result,omitempty"` +} + +// FuturesMarketStatus represents the market status for a futures product. +type FuturesMarketStatus struct { + ProductCode string `json:"product_code"` + ExchangeCode string `json:"exchange_code"` + MarketStatus string `json:"market_status"` + Timestamp int64 `json:"timestamp"` +} + +// ListFuturesMarketStatusesResponse defines the response for listing market statuses. +type ListFuturesMarketStatusesResponse struct { + BaseResponse + Results []FuturesMarketStatus `json:"results,omitempty"` +} + +// FuturesProduct represents a futures product. +type FuturesProduct struct { + ProductCode string `json:"product_code"` + Name string `json:"name"` + AssetClass string `json:"asset_class"` + ExchangeCode string `json:"exchange_code"` + Sector string `json:"sector"` + SubSector string `json:"sub_sector"` + Type string `json:"type"` +} + +// ListFuturesProductsResponse defines the response for listing futures products. +type ListFuturesProductsResponse struct { + BaseResponse + Results []FuturesProduct `json:"results,omitempty"` +} + +// GetFuturesProductResponse defines the response for retrieving a specific futures product. +type GetFuturesProductResponse struct { + BaseResponse + Result FuturesProduct `json:"result,omitempty"` +} + +// FuturesSchedule represents a trading schedule for futures. +type FuturesSchedule struct { + MarketIdentifierCode string `json:"market_identifier_code"` + ProductCode string `json:"product_code"` + ProductName string `json:"product_name"` + SessionEndDate Date `json:"session_end_date"` + Schedule []ScheduleEvent `json:"schedule"` +} + +// ScheduleEvent represents a single event in a schedule. +type ScheduleEvent struct { + Event string `json:"event"` + Timestamp string `json:"timestamp"` +} + +// ListFuturesSchedulesResponse defines the response for listing futures schedules. +type ListFuturesSchedulesResponse struct { + BaseResponse + Results []FuturesSchedule `json:"results,omitempty"` +} + +// ListFuturesProductSchedulesResponse defines the response for listing schedules for a specific product. +type ListFuturesProductSchedulesResponse struct { + BaseResponse + Results []FuturesSchedule `json:"results,omitempty"` +} + +// FuturesTrade represents a trade event for futures. +type FuturesTrade struct { + Price float64 `json:"price"` + Size float64 `json:"size"` + Ticker string `json:"ticker"` + Timestamp int64 `json:"timestamp"` +} + +// ListFuturesTradesResponse defines the response for listing futures trades. +type ListFuturesTradesResponse struct { + BaseResponse + Results []FuturesTrade `json:"results,omitempty"` +} + +// FuturesQuote represents a quote event for futures. +type FuturesQuote struct { + AskPrice float64 `json:"ask_price"` + AskSize float64 `json:"ask_size"` + BidPrice float64 `json:"bid_price"` + BidSize float64 `json:"bid_size"` + Ticker string `json:"ticker"` + Timestamp int64 `json:"timestamp"` +} + +// ListFuturesQuotesResponse defines the response for listing futures quotes. +type ListFuturesQuotesResponse struct { + BaseResponse + Results []FuturesQuote `json:"results,omitempty"` +} diff --git a/rest/polygon.go b/rest/polygon.go index f5b56838..7d4ebb3e 100644 --- a/rest/polygon.go +++ b/rest/polygon.go @@ -17,6 +17,7 @@ type Client struct { SnapshotClient IndicatorsClient SummariesClient + FuturesClient VX VXClient } @@ -47,6 +48,7 @@ func newClient(apiKey string, hc *http.Client) *Client { ReferenceClient: ReferenceClient{Client: c}, TradesClient: TradesClient{Client: c}, SnapshotClient: SnapshotClient{Client: c}, + FuturesClient: FuturesClient{Client: c}, VX: VXClient{Client: c}, } } diff --git a/websocket/models/models.go b/websocket/models/models.go index eecc1a94..7def9d98 100644 --- a/websocket/models/models.go +++ b/websocket/models/models.go @@ -403,3 +403,40 @@ type FairMarketValue struct { // The Timestamp in nanoseconds. Timestamp int64 `json:"t,omitempty"` } + +// FuturesTrade represents a futures trade event. +type FuturesTrade struct { + EventType + Symbol string `json:"sym,omitempty"` + Price float64 `json:"p,omitempty"` + Size int64 `json:"s,omitempty"` + Timestamp int64 `json:"t,omitempty"` +} + +// FuturesQuote represents a futures quote event. +type FuturesQuote struct { + EventType + Symbol string `json:"sym,omitempty"` + BidPrice float64 `json:"bp,omitempty"` + BidSize int64 `json:"bs,omitempty"` + AskPrice float64 `json:"ap,omitempty"` + AskSize int64 `json:"as,omitempty"` + Timestamp int64 `json:"t,omitempty"` +} + +// FuturesAggregate represents an aggregate event (e.g., second or minute) for a futures contract. +type FuturesAggregate struct { + EventType string `json:"ev,omitempty"` + Symbol string `json:"sym,omitempty"` + Volume float64 `json:"v,omitempty"` + AccumulatedVolume float64 `json:"av,omitempty"` + OfficialOpenPrice float64 `json:"op,omitempty"` + Open float64 `json:"o,omitempty"` + Close float64 `json:"c,omitempty"` + High float64 `json:"h,omitempty"` + Low float64 `json:"l,omitempty"` + AveragePrice float64 `json:"a,omitempty"` + StartTimestamp int64 `json:"s,omitempty"` + EndTimestamp int64 `json:"e,omitempty"` + OTC bool `json:"otc,omitempty"` +}