0

i'm just beginning to learn to code and i want to apologize in advance if this question is trivial.

ive been trying to find a way to feed stock market data into python real time and came across this blog http://www.quantatrisk.com/2015/05/07/hacking-google-finance-in-pre-market-trading-python/

Below is the script i copied and pasted.

import urllib2  # works fine with Python 2.7.9 (not 3.4.+)
import json
import time

def fetchPreMarket(symbol, exchange):
    link = "http://finance.google.com/finance/info?client=ig&q="
    url = link+"%s:%s" % (exchange, symbol)
    u = urllib2.urlopen(url)
    content = u.read()
    data = json.loads(content[3:])
    info = data[0]
    t = str(info["elt"])    # time stamp
    l = float(info["l"])    # close price (previous trading day)
    p = float(info["el"])   # stock price in pre-market (after-hours)
    return (t,l,p)


p0 = 0
while True:
    t, l, p = fetchPreMarket("AAPL","NASDAQ")
    if(p!=p0):
        p0 = p
        print("%s\t%.2f\t%.2f\t%+.2f\t%+.2f%%" % (t, l, p, p-l,
                                                 (p/l-1)*100.))
    time.sleep(60)

it seems to be a great code except when i run it, i get the following error message

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-11-012ec6dc7b0c> in <module>()
     18 p0 = 0
     19 while True:
---> 20     t, l, p = fetchPreMarket("AAPL","NASDAQ")
     21     if(p!=p0):
     22         p0 = p

<ipython-input-11-012ec6dc7b0c> in fetchPreMarket(symbol, exchange)
     10     data = json.loads(content[3:])
     11     info = data[0]
---> 12     t = str(info["elt"])    # time stamp
     13     l = float(info["l"])    # close price (previous trading day)
     14     p = float(info["el"])   # stock price in pre-market (after-hours)

KeyError: 'elt'

I tried modifying fetchPreMarket such that it just outputs info = data[0] but when i tried 'print info', nothing came of it.

Thanks in advance

stratofortress
  • 453
  • 1
  • 9
  • 21
  • Print `data` instead. What does it look like? – OneCricketeer Feb 24 '16 at 19:32
  • if i suppress `t,l,p` in the function and do `data = fetchPreMarket("AAPL","NASDAQ") print(data) time.sleep(60) ` , then i get `[{u'c': u'+0.95', u'ccol': u'chg', u'e': u'NASDAQ', u'ltt': u'2:40PM EST', u'cp_fix': u'1.00', u'c_fix': u'0.95', u'l': u'95.64', u's': u'0', u'lt': u'Feb 24, 2:40PM EST', u'pcls_fix': u'94.69', u't': u'AAPL', u'lt_dts': u'2016-02-24T14:40:36Z', u'l_fix': u'95.64', u'cp': u'1.00', u'id': u'22144', u'l_cur': u'95.64'}]` – stratofortress Feb 24 '16 at 19:42
  • 2
    @stratofortress [Edit] your question instead of posting a bunch of code and data in a comment. – elixenide Feb 24 '16 at 19:50
  • @EdCottrell my apologies – stratofortress Feb 24 '16 at 20:15

2 Answers2

2

So... The Google Finance API has been discontinued. I am surprised that link works, but there is no "etl" (or "el") key in the data.

And so, you'll get KeyError: 'elt' at info["elt"]

For reference,

{
"id": "22144"
,"t" : "AAPL"
,"e" : "NASDAQ"
,"l" : "95.52"
,"l_fix" : "95.52"
,"l_cur" : "95.52"
,"s": "0"
,"ltt":"2:34PM EST"
,"lt" : "Feb 24, 2:34PM EST"
,"lt_dts" : "2016-02-24T14:34:54Z"
,"c" : "+0.83"
,"c_fix" : "0.83"
,"cp" : "0.88"
,"cp_fix" : "0.88"
,"ccol" : "chg"
,"pcls_fix" : "94.69"
}

You may have better luck with the googlefinance or yahoo-finance python modules rather than directly calling the API address.

It is worth noting that the Yahoo API is not "realtime", though. It is about a 15 minute delayed quote.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • 1
    It looks like `l_cur` is the current price, `pcls_fix` is the previous close price, and `lt_dts` is the date-timestamp. – Charlie Haley Feb 24 '16 at 19:58
  • 2
    @stratofortress - you could use `"lt"` instead of `"etl"` and `"pcls_fix"` instead of `"el"`. Those appear to be the same numbers that the blog is extracting – OneCricketeer Feb 24 '16 at 20:03
  • @cricket_007 Changing `"elt"` to `"lt"` and `"el"` to `"pcls_fix"` from the [original code](http://www.quantatrisk.com/2015/05/07/hacking-google-finance-in-pre-market-trading-python/) worked. – 3kstc Jan 02 '17 at 21:01
0

If you don't want to use googlefinance package, you can create your own parser with BeautifulSoup.

Check code in online IDE that uses BeautifulSoup.

from bs4 import BeautifulSoup
import requests, json, lxml, re
from itertools import zip_longest


def scrape_google_finance(ticker: str):
    # https://docs.python-requests.org/en/master/user/quickstart/#passing-parameters-in-urls
    params = {
        "hl": "en" # language
        }

    # https://docs.python-requests.org/en/master/user/quickstart/#custom-headers
    # https://www.whatismybrowser.com/detect/what-is-my-user-agent
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Safari/537.36",
        }

    html = requests.get(f"https://www.google.com/finance/quote/{ticker}", params=params, headers=headers, timeout=30)
    soup = BeautifulSoup(html.text, "lxml")    
    
    ticker_data = {"ticker_info": {},
                    "right_panel_data": {},
                    "finance_perfomance": {"table": []}
                    }
    
    ticker_data["ticker_info"]["title"] = soup.select_one(".zzDege").text
    ticker_data["ticker_info"]["current_price"] = soup.select_one(".AHmHk .fxKbKc").text
    
    right_panel_keys = soup.select(".gyFHrc .mfs7Fc")
    right_panel_values = soup.select(".gyFHrc .P6K39c")
    
    for key, value in zip_longest(right_panel_keys, right_panel_values):
        key_value = key.text.lower().replace(" ", "_")

        ticker_data["right_panel_data"][key_value] = value.text
    

    if soup.select(".slpEwd .roXhBd"):
        # https://regex101.com/r/Sf2TaC/1
        fin_perf_col_2 = re.search(r"\w+\s?\d{4}", soup.select_one(".PFjsMe+ .yNnsfe").text).group(0)                # e.g. JUN 2022
        fin_perf_col_3 = soup.select_one(".PFjsMe~ .yNnsfe+ .yNnsfe").text       # e.g. Year/year change
         
        for fin_perf in soup.select(".slpEwd .roXhBd"):
            if fin_perf.select(".rsPbEe"):
                perf_key = fin_perf.select_one(".rsPbEe").text                   # e.g. Revenue, Net Income, Operating Income..
                perf_value_col_1 = fin_perf.select_one(".QXDnM").text            #  48.23B, ... 

                try:
                  perf_value_col_2 = fin_perf.select_one(".gEUVJe .JwB6zf").text # -21.82%, ...
                except:
                  perf_value_col_2 = None  # 
                
                ticker_data["finance_perfomance"]["table"].append({
                    perf_key: {
                        fin_perf_col_2: perf_value_col_1,
                        fin_perf_col_3: perf_value_col_2
                    }
                })
    else:
        ticker_data["finance_perfomance"]["error"] = f"No 'finence perfomance table' for {ticker}."

    return ticker_data

  
data = scrape_google_finance(ticker="AAPL:NASDAQ")

print(json.dumps(data, indent=2))

Example output

[
    {
  "ticker_info": {
    "title": "Apple Inc",
    "current_price": "$174.55"
  },
  "right_panel_data": {
    "previous_close": "$173.03",
    "day_range": "$172.57 - $176.15",
    "year_range": "$129.04 - $182.94",
    "market_cap": "2.81T USD",
    "avg_volume": "68.49M",
    "p/e_ratio": "28.84",
    "dividend_yield": "0.53%",
    "primary_exchange": "NASDAQ",
    "ceo": "Tim Cook",
    "founded": "Apr 1, 1976",
    "headquarters": "Cupertino, CaliforniaUnited States",
    "website": "apple.com",
    "employees": "154,000"
  },
  "finance_perfomance": {
    "table": [
      {
        "Revenue": {
          "Jun 2022": "82.96B",
          "Y/Y change": "1.87%"
        }
      },
      {
        "Operating expense": {
          "Jun 2022": "12.81B",
          "Y/Y change": "15.10%"
        }
      },
      {
        "Net income": {
          "Jun 2022": "19.44B",
          "Y/Y change": "-10.59%"
        }
      # ...
]

There's a scrape Google Finance Ticker Quote Data in Python blog post if you need to scrape more data from Google Finance.

Denis Skopa
  • 1
  • 1
  • 1
  • 7