westonplatter / fast_arrow

(no longer maintained) A simple yet robust (stock+options) API client for Robinhood
MIT License
127 stars 37 forks source link

HTTPError for a particular slice of expiration dates #80

Closed pratik-r closed 5 years ago

pratik-r commented 5 years ago

Hi, I was querying some options data for SPY, and I ran into a strange error involving Option.mergein_marketdata. I've included some code that replicates this error. Basically, it throws a HTTPError when I query options data for a particular combination of expiration dates. In this case, it's ["2019-05-10", "2019-05-17"]. Any idea why this is happening? How can I fix it?

Thanks.

Version of "fast_arrow": 0.3.1 What you did:

from fast_arrow import Client, Stock, OptionChain, Option
symbol = "SPY"
stock = Stock.fetch(client, symbol)
option_chain = OptionChain.fetch(client, stock["id"], symbol)
exp_dates = option_chain["expiration_dates"][slice(7,11,3)]
ops = Option.in_chain(client, option_chain['id'], exp_dates)
ops = Option.mergein_marketdata_list(client, ops) # error occurs here

What you expected to happen: Get the options data

What actually happened:

HTTPError                                 Traceback (most recent call last)
<ipython-input-155-c923376ae3fe> in <module>
      5 exp_dates = option_chain["expiration_dates"][slice(7,11,3)]
      6 ops = Option.in_chain(client, option_chain['id'], exp_dates)
----> 7 ops = Option.mergein_marketdata_list(client, ops)

~\Miniconda3\lib\site-packages\fast_arrow\resources\option.py in mergein_marketdata_list(cls, client, options)
     90     def mergein_marketdata_list(cls, client, options):
     91         ids = [x["id"] for x in options]
---> 92         mds = OptionMarketdata.quotes_by_instrument_ids(client, ids)
     93         mds = [x for x in mds if x]
     94 

~\Miniconda3\lib\site-packages\fast_arrow\resources\option_marketdata.py in quotes_by_instrument_ids(cls, client, ids)
     13         base_url = "https://api.robinhood.com/options/instruments/"
     14         id_urls = ["{}{}/".format(base_url, _id) for _id in ids]
---> 15         return cls.quotes_by_instrument_urls(client, id_urls)
     16 
     17 

~\Miniconda3\lib\site-packages\fast_arrow\resources\option_marketdata.py in quotes_by_instrument_urls(cls, client, urls)
     27             url = "https://api.robinhood.com/marketdata/options/"
     28             params = {"instruments": ",".join(_urls)}
---> 29             data = client.get(url, params=params)
     30             if data and "results" in data:
     31                 partial_results = data["results"]

~\Miniconda3\lib\site-packages\fast_arrow\client.py in get(self, url, params, retry)
     56                 attempts += 1
     57                 if res.status_code in [400]:
---> 58                     raise e
     59                 elif retry and res.status_code in [403]:
     60                     self.relogin_oauth2()

~\Miniconda3\lib\site-packages\fast_arrow\client.py in get(self, url, params, retry)
     51             try:
     52                 res = requests.get(url, headers=headers, params=params, timeout=15, verify=self.certs)
---> 53                 res.raise_for_status()
     54                 return res.json()
     55             except requests.exceptions.RequestException as e:

~\Miniconda3\lib\site-packages\requests\models.py in raise_for_status(self)
    938 
    939         if http_error_msg:
--> 940             raise HTTPError(http_error_msg, response=self)
    941 
    942     def close(self):

HTTPError: 400 Client Error: Bad Request for url: https://api.robinhood.com/marketdata/options/?instruments=https%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F9252c014-91aa-4e4a-ac5b-f3978253b028%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F10380fa4-4598-4690-b844-c6e3e3577599%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F3f54d54f-8327-400c-84fd-7efc2da0290f%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F1ac4f880-1792-4df7-9fd1-ab583f803d5d%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F60f2ecd6-641b-47d1-9988-409f9587b090%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fd4a48477-9584-44ee-971a-ac5a872e5322%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F61447399-6dfc-46a6-8031-47c4c0ff47be%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F524e81ae-218c-43c6-9dba-4b510425c238%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F35162977-211b-4b57-aaa1-68d0eb0cd475%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fc9264f2f-db7b-48f0-9829-8831d556d5e1%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F94d8cc2e-ad43-4ed6-bdd3-413d670aca37%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fef563b2e-7c7f-47ea-b494-37929fbe1b73%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Ffc6a866d-4ea6-431b-8643-22bd45591bee%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F0f7e2c72-f145-4696-a221-568c6673b946%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Ff01bea56-a18b-44c8-8d91-41f3728f7c95%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F208ae270-02ea-416c-a9b4-f54d20059b02%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fb41bc855-545b-4cbc-84d6-9a0c603fa78e%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F5ec21a39-3302-493f-8a68-929a3803d6f2%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fcdac0051-3287-478c-bea2-4f94e61712c1%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F8efb746a-8360-41f7-8275-d0d39b256c15%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fe8e7d6ce-41f4-4b94-8c8f-21efa7a84581%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F6129126a-407f-4132-8c15-9cb88d22e79a%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F1c1844c5-7ef5-46bf-b9a1-46545e8e77da%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F72012f8d-38d9-4552-8d78-075259bdca95%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fc5977ab8-3654-436a-a64d-bde332e5d4a8%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F2f354e7a-63c5-42cc-a9e2-84e7ff411c6b%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F0c1a6cd4-9c62-4024-a374-f335cb84c410%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F3120055c-ae3e-4de0-96cb-942149dad32b%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fa17c9cd9-394e-4b1b-a90f-01e5ff09194d%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F5b0d6c17-6000-432d-9468-416eff21d7f9%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fce4a1130-a936-4c7e-8f14-7f121502e97e%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fb0458a87-9ebc-49a5-9fc9-b1f48c1c0605%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F0311eec6-a134-4393-9b96-bd2532b83b5c%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fce1b8b73-cd7c-4e6c-af7b-014f020d07d2%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F9d1b349f-d7c4-40c0-8e16-06615bdeab56%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fca2ba899-ce6d-41e2-ae5c-788c10593713%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fed55e3de-8608-4f33-8b64-2fd07c606b05%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fbf4a26c0-9938-4954-a463-9f73a4aff86f%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Ff61bd27d-3a9a-4457-be41-90c585e50c60%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fbff80851-3022-4ee3-8b7a-5a2a58e51bb7%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fb6c02b9c-9d47-4af9-95d7-297a2887c656%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Ffb2022d6-778d-4ba6-aa1c-87bcc6334b25%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F21376374-fe1e-4f83-8031-911cdf774870%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F55eeef12-3eb8-4db7-a052-b41f0c0eeb3c%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F8f8ecfa9-0a71-4cdf-b884-16c725178e67%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F077aef4f-9600-4431-827d-8b04d546f141%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F36736135-dc31-4cff-9956-3a78eb0990cd%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F9704b82a-95b2-4d03-8e28-b4ce5a8cc4b0%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2Fe0dc5fd9-1f24-44f0-857a-45543f2043f8%2F%2Chttps%3A%2F%2Fapi.robinhood.com%2Foptions%2Finstruments%2F39914fad-025f-4974-88bf-9a7c1b004eaf%2F
AmeliorateOr commented 5 years ago

I get the same error when trying to use the Option.mergein_marketdata. It worked for me 5 days ago, but it seems to have stopped working recently. Let me know if you find anything out. I'll do the same.

pratik-r commented 5 years ago

I'm currently using a temporary fix. Basically I iterate over the expiration dates:

ops_all = []
for date in exp_dates:
    ops = Option.in_chain(client, option_chain['id'], [date])
    ops_all.append(Option.mergein_marketdata_list(client, ops))

It's a bit slower than the regular method, but throws HTTP errors less often.

westonplatter commented 5 years ago

@pratik-r I tried running your script today for SPY using expiration dates = ['2019-10-11', '2019-10-18'], and didn't see the issue you described. Are you still running into this issue?

pratik-r commented 5 years ago

@westonplatter I still face this error sometimes, but I've realized this has to do with Robinhood market data during off market hours, and is not a fastarrow issue. I'm closing this now.

westonplatter commented 5 years ago

@pratik-r hey, sorry to hear it's an issue we can't correct with fast_arrow code. Thanks for replying back and contributing your insight on the issue.