diff --git a/contrib/alpacabkfeeder/README.md b/contrib/alpacabkfeeder/README.md index 021d9c04..746cdac6 100644 --- a/contrib/alpacabkfeeder/README.md +++ b/contrib/alpacabkfeeder/README.md @@ -54,6 +54,10 @@ bgworkers: # environment variables. api_key_id: "foobar" api_secret_key: "fizzbuzz" + # auth method for the Alpaca API. "basic" (default value. basic authentication is used.) + # or "header" ("APCA-API-KEY-ID" and "APCA-API-SECRET-KEY" HTTP headers are used). + # This config can be manually overridden by "APCA_API_AUTH_METHOD" environmental variable. + #auth_method: "basic" # Timeout: Due to the restriction of the Alpaca API Client library used in this plugin, # Alpaca API Client timeout can be updated only by "APCA_API_CLIENT_TIMEOUT" environmental variable. # Please set the env var to a duration string is a possibly signed sequence of diff --git a/contrib/alpacabkfeeder/alpacav2.go b/contrib/alpacabkfeeder/alpacav2.go index 08ed4855..ff427e7e 100644 --- a/contrib/alpacabkfeeder/alpacav2.go +++ b/contrib/alpacabkfeeder/alpacav2.go @@ -106,6 +106,7 @@ func apiClient(config *configs.DefaultConfig) *api.Client { PolygonKeyID: config.APIKeyID, Secret: config.APISecretKey, // OAuth: os.Getenv(EnvApiOAuth), + AuthMethod: api.AuthMethodFromString(config.AuthMethod), } if config.APIKeyID == "" || config.APISecretKey == "" { // if empty, get from env vars diff --git a/contrib/alpacabkfeeder/api/client.go b/contrib/alpacabkfeeder/api/client.go index 5748b888..5158bc66 100644 --- a/contrib/alpacabkfeeder/api/client.go +++ b/contrib/alpacabkfeeder/api/client.go @@ -35,12 +35,12 @@ func defaultDo(c *Client, req *http.Request) (*http.Response, error) { if c.credentials.OAuth != "" { req.Header.Set("Authorization", "Bearer "+c.credentials.OAuth) } else { - if strings.Contains(req.URL.String(), "sandbox") { - // Add Basic Auth - req.SetBasicAuth(c.credentials.ID, c.credentials.Secret) - } else { + if c.credentials.AuthMethod == HeaderAuth { req.Header.Set("APCA-API-KEY-ID", c.credentials.ID) req.Header.Set("APCA-API-SECRET-KEY", c.credentials.Secret) + } else { + // default: Basic Auth + req.SetBasicAuth(c.credentials.ID, c.credentials.Secret) } } @@ -117,6 +117,13 @@ type Client struct { credentials *APIKey } +type AuthMethod int + +const ( + BasicAuth = iota + HeaderAuth +) + func SetBaseUrl(baseUrl string) { base = baseUrl } @@ -292,7 +299,6 @@ func (c *Client) ListAssets(status *string) ([]v1.Asset, error) { } u.RawQuery = q.Encode() - resp, err := c.get(u) if err != nil { return nil, err diff --git a/contrib/alpacabkfeeder/api/credentials.go b/contrib/alpacabkfeeder/api/credentials.go index 449f97f7..44319163 100644 --- a/contrib/alpacabkfeeder/api/credentials.go +++ b/contrib/alpacabkfeeder/api/credentials.go @@ -13,6 +13,7 @@ var ( const ( EnvApiKeyID = "APCA_API_KEY_ID" EnvApiSecretKey = "APCA_API_SECRET_KEY" + EnvAuthMethod = "APCA_API_AUTH_METHOD" EnvApiOAuth = "APCA_API_OAUTH" EnvPolygonKeyID = "POLY_API_KEY_ID" ) @@ -22,6 +23,7 @@ type APIKey struct { Secret string OAuth string PolygonKeyID string + AuthMethod AuthMethod } // Credentials returns the user's Alpaca API key ID @@ -33,10 +35,25 @@ func Credentials() *APIKey { } else { polygonKeyID = os.Getenv(EnvApiKeyID) } - return &APIKey{ + apiKey := &APIKey{ ID: os.Getenv(EnvApiKeyID), PolygonKeyID: polygonKeyID, Secret: os.Getenv(EnvApiSecretKey), OAuth: os.Getenv(EnvApiOAuth), } + if am := os.Getenv(EnvAuthMethod); am != "" { + apiKey.AuthMethod = AuthMethodFromString(am) + } + return apiKey +} + +func AuthMethodFromString(s string) AuthMethod { + switch s { + case "basic": + return BasicAuth + case "header": + return HeaderAuth + default: + return BasicAuth + } } diff --git a/contrib/alpacabkfeeder/configs/config.go b/contrib/alpacabkfeeder/configs/config.go index a1de6115..857de85d 100644 --- a/contrib/alpacabkfeeder/configs/config.go +++ b/contrib/alpacabkfeeder/configs/config.go @@ -32,6 +32,7 @@ type DefaultConfig struct { Timeframe string `json:"timeframe"` APIKeyID string `json:"api_key_id"` APISecretKey string `json:"api_secret_key"` + AuthMethod string `json:"auth_method"` OpenHourNY, OpenMinuteNY int CloseHourNY, CloseMinuteNY int ExtendedHours bool `json:"extended_hours"` diff --git a/contrib/alpacabkfeeder/feed/worker.go b/contrib/alpacabkfeeder/feed/worker.go index c07a763b..10a9eca8 100644 --- a/contrib/alpacabkfeeder/feed/worker.go +++ b/contrib/alpacabkfeeder/feed/worker.go @@ -51,7 +51,7 @@ func (w *Worker) tryPrintErr() { }() } -// try calls GetQuotes endpoint of Alpaca API, +// try calls GetSnapshots endpoint of Alpaca API, // convert the API response to a ColumnSeriesMap and write it to the marketstore. func (w *Worker) try() error { // check if it needs to work now @@ -66,6 +66,7 @@ func (w *Worker) try() error { len(symbls), err, ) } + log.Info("successfully got snapshot data from Alpaca API. len(symbols)=%v", len(symbls)) // write SnapShot data err = w.SnapshotWriter.Write(snapshots)