Home > database >  Append values in list nested in dictionary
Append values in list nested in dictionary

Time:06-11

I would like to add stock prices to a dictionary and append the recent value at the end. It should be running till cancelled. So a while True loop might be appropriate? Furthermore I would like to have the amount of prices in the list restricted to the recent 3. I use yfinance as a stock price library.

What I need is that it appends the price of stock#1 to the list within the dictionary. Then #2, then #3. Then starts over with #1 again but appends it to the same dictionary. In my approach it iterates over stock#1 over and over again.

Result should be like:

{
    "AAPL": [137.13, 137.45, 138.02],
    "TESL": [696.69, 696.72, 670.1],
    "MSFT": [252.99, 253.01, 254.01],
}

What I tried so far, but didn't work is:

stocks = ['AAPL', 'TESL', 'MSFT']
dict_akt = {}

while True:
    list_temp = []
    for stock in stocks:
        sto = yf.Ticker(stock)
        cur_price = sto.info['currentPrice']
        list_temp.append(cur_price)

        dict_akt[stock] = list_temp

The bad output is:

{
    "AAPL": [137.13, 696.69, 252.99],
    "TSLA": [137.13, 696.69, 252.99],
    "MSFT": [137.13, 696.69, 252.99],
}

CodePudding user response:

you should just create lists in the dict_akt and manipulate those directly

stocks = ['AAPL', 'TESL', 'MSFT']
dict_akt = {}

# init lists
for stock in stocks:
    dict_akt[stock] = []

while True:
    for stock in stocks:
        sto = yf.Ticker(stock)
        cur_price = sto.info['currentPrice']
        dict_akt[stock].append(cur_price)
        #check size and pop first element if desired size exceeded
        if len(dict_akt[stock]) > 3:
            dict_akt[stock].pop(0)

CodePudding user response:

You need to somehow break out of your loop in order to see any results so let's assume that you want to run for at least some period of time.

The public APIs that underpin yfinance are notoriously slow.

Note also that the info dictionary may not always contain keys that you might expect, so you should check.

This code manages the size of the lists (latest three entries) "manually". You could consider using a deque but that would depend on how you wanted to access the results.

import time
import yfinance
import requests_cache

results = dict()
tickers = 'AAPL', 'TESL', 'MSFT', 'GOOG', 'ORCL'
duration = 60 # seconds
session = requests_cache.CachedSession('yfinance.cache')
session.headers['User-agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15'

start = time.perf_counter()

while time.perf_counter() - start < duration:
    for ticker in tickers:
        stock = yfinance.Ticker(ticker, session=session)
        if (price := stock.info.get('currentPrice')):
            results.setdefault(ticker, []).append(price)
            if len(results[ticker]) > 3:
                results[ticker].pop(0)

print(results)

Output:

{'AAPL': [137.13, 137.13, 137.13], 'MSFT': [252.99, 252.99, 252.99], 'GOOG': [2228.55, 2228.55, 2228.55], 'ORCL': [67.14, 67.14, 67.14]}

Notes:

All the values are the same because this was run on a non-trading day (Saturday). The currentPrice key is missing for TESL.

Python 3.8 required

You will need to pip install requests_cache if you don't already have it.

Use of a cached session can potentially improve performance

  • Related