jmfernandes / robin_stocks

This is a library to use with Robinhood Financial App. It currently supports trading crypto-currencies, options, and stocks. In addition, it can be used to get real time ticker information, assess the performance of your portfolio, and can also get tax documents, total dividends paid, and more. More info at
http://www.robin-stocks.com
MIT License
1.74k stars 468 forks source link

Robin_stocks 3.0.5 not updating stock historicals for TQQQ and SQQQ during 24-hour markets #420

Open SingularityMan opened 1 year ago

SingularityMan commented 1 year ago

robin_stocks doesn't seem to be getting stock historicals from Sunday. It can only go back to Friday. I tried this with this code:


# get the current date and time
        now = datetime.datetime.now(pytz.timezone('US/Eastern'))

        # if today is Sunday, get the date and time for '7:00pm EST last Friday'
        # otherwise, get the date and time for '7:00pm EST yesterday'
        if now.weekday() == 0:  # Sunday
            start_time = now - relativedelta(days=3)
        else:
            start_time = now - relativedelta(days=1)

        # set the time to '7:00pm EST'
        start_time = start_time.replace(hour=19, minute=0, second=0, microsecond=0)

        # format start_time for robin_stocks API
        start_time_str = start_time.strftime('%Y-%m-%dT%H:%M:%S') + 'Z'

        # get the date and time for '7:00pm EST one week ago'
        end_time = start_time - relativedelta(weeks=1)

        # initialize historical_data list
        historical_data = []

        # fetch historical data for 'UPRO' and 'SPXU' from end_time to start_time
        current_time = end_time
        while current_time < start_time:
            # format current_time for robin_stocks API
            current_time_str = current_time.strftime('%Y-%m-%dT%H:%M:%S')

            # fetch historical data for 'UPRO' and 'SPXU' for current day
            data = r.get_stock_historicals(['UPRO', 'SPXU'], span='week', bounds='regular', interval='hour', info=None)

            # add data to historical_data list
            historical_data.extend(data)

            # increment current_time by one day
            current_time += relativedelta(days=1)
            for hist in historical_data:
                print(hist)

        # Print start_time_str
        # print('Start Time:', start_time_str)

        # Print the historical data
        # print('Historical Data:', historical_data)

        # find the data point that corresponds to '7:00pm EST yesterday'
        yesterday_close = []
        for data_point in historical_data:
            if 'UPRO' in data_point['symbol']:
                if data_point['begins_at'] == start_time_str:
                    yesterday_close.append(float(data_point['close_price']))

            if 'SPXU' in data_point['symbol']:
                if data_point['begins_at'] == start_time_str:
                    yesterday_close.append(float(data_point['close_price']))

    # Get the current price of the ETFs
    latest_price = r.get_latest_price(['UPRO', 'SPXU'], includeExtendedHours=True)

    # Get the current and previous close price of the ETFs and store in variables
    ETFClose = yesterday_close
    ETFCurrent = latest_price

And the final timestamp for historical_data prints this out for TQQQ and SQQQ:


{'begins_at': '2023-07-28T19:00:00Z', 'open_price': '16.910000', 'close_price': '16.959900', 'high_price': '17.030000', 'low_price': '16.860000', 'volume': 11575948, 'session': 'reg', 'interpolated': False, 'symbol': 'SQQQ'}

{'begins_at': '2023-07-28T19:00:00Z', 'open_price': '45.340000', 'close_price': '45.240000', 'high_price': '45.469900', 'low_price': '45.070000', 'volume': 6125662, 'session': 'reg', 'interpolated': False, 'symbol': 'TQQQ'}

This means Sunday is not being registered as a trading day in the API. I also tried this:


yesterday_close = r.get_quotes(['TQQQ', 'SQQQ'], info='adjusted_previous_close')
        print("yesterday_close:", yesterday_close)

# Output:

yesterday_close: ['42.900000', '17.930000'] # This is last Friday's closing price, not Sunday. Today is Monday

Is there something I'm missing here? maybe I got the timedeltas wrong?

ghost commented 1 year ago

I have noticed the same thing.

You should try stocks.get_stock_historicals('TQQQ', interval='5minute', span='day', bounds='extended')

This, for some reason, only works with a span=day. However, this seems to be a restriction set by the API: https://github.com/jmfernandes/robin_stocks/blob/3e3d74e65e672fb4b31217b9b5e78353d5713eec/robin_stocks/robinhood/stocks.py#L560C8-L560C8

If you do this manually:

from robin_stocks.robinhood.helper import get_output, request_get
from robin_stocks.robinhood.urls import historicals_url

url = historicals_url()
payload = {'symbols': ','.join(['TQQQ']),
           'interval': '5minute',
           'span': 'week',
           'bounds': 'extended'}

data = request_get(url, 'results', payload)
data[0]['historicals']

It will return history for extended hours for span="day" and span="week". Longer than that doesnt work.

So perhaps the restriction in the API should be updated?

SingularityMan commented 1 year ago

I think the API may need to be updated. I ran a modified version of your code:


url = historicals_url()
payload = {'symbols': ','.join(['TQQQ']),
           'interval': '5minute',
           'span': 'week',
           'bounds': 'extended'}

data = request_get(url, 'results', payload)
for day in data[0]['historicals']:
    print(day)
    if day['begins_at'] == '2023-07-30T18:00:00Z':
        print('Begins at: ', day['begins_at'])
        print('Close price: ', day['close_price'])

And it returned dates between 07/28/2023 - 08/01/2023 but it does not show 07/30/2023 (Sunday)

So In terms of stock historicals we're sitting ducks until the API is updated.

ghost commented 1 year ago

Alright here we are!

from robin_stocks.robinhood.urls import historicals_url

url = historicals_url()
payload = {'symbols': ','.join(['TQQQ']),
           'interval': '5minute',
           'span': 'week',
           'bounds': '24_7'}

data = request_get(url, 'results', payload)

But the price over the weekend is static:

{'begins_at': '2023-07-30T00:00:00Z', 'open_price': '45.379900', 'close_price': '45.379900', 'high_price': '45.379900', 'low_price': '45.379900', 'volume': 0, 'session': 'post', 'interpolated': True}
{'begins_at': '2023-07-30T00:10:00Z', 'open_price': '45.379900', 'close_price': '45.379900', 'high_price': '45.379900', 'low_price': '45.379900', 'volume': 0, 'session': 'post', 'interpolated': True}
ghost commented 1 year ago

Some help would be appreciated!

Adelantado commented 1 year ago

My code includes some historicals, which were implemented before the 24/7 introduction. I believe bounds = 'regular' was returning Mon/Friday prices on regular stocks; but to make it work with crypto and pull weekend prices I had to code bounds as = '24_7'. Haven't check but maybe that's your answer ??

ghost commented 1 year ago

Not really - dont mean to be fastidious but this should be something easily recoverable from the API. Especially for stocks that trade 24/7.

Perhaps @jmfernandes can chime in here?

Something that i noticed is that interpolated=true for prices that are fetched over the weekend. Could there be a solution to this?

I have tried to set interpolated=False in the payload but it doesnt make a difference