{"id":362,"date":"2017-06-08T20:31:34","date_gmt":"2017-06-08T20:31:34","guid":{"rendered":"http:\/\/warmcat.uk\/?p=362"},"modified":"2020-06-06T02:14:08","modified_gmt":"2020-06-06T02:14:08","slug":"raspberry-pi-stock-ticker","status":"publish","type":"post","link":"https:\/\/warmcat.uk\/?p=362","title":{"rendered":"Raspberry Pi Stock Ticker"},"content":{"rendered":"\n<p>UPDATE: Yahoo\u2019s ystockquote is no longer available. However one person emailed me advising that it\u2019s still possible to obtain Yahoo\u2019s stock by parsing data with the python package \u201cBeautifulSoup\u201d.<\/p>\n\n\n\n<p>I love tinkering with displays, as you can see with my post about the <a rel=\"noreferrer noopener\" href=\"http:\/\/www.fartmagnet.co.uk\/warmcat\/?p=97\" target=\"_blank\">DLR2416<\/a>, so I purchased Adafruit\u2019s  2.2\u2033 PiTFT plug-in display from <a rel=\"noreferrer noopener\" href=\"http:\/\/shop.pimoroni.com\" target=\"_blank\">www.pimoroni.com<\/a> to try out.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"http:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1141-e1560026047967-1024x768.jpg\" alt=\"\" class=\"wp-image-363\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1141-e1560026047967-1024x768.jpg 1024w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1141-e1560026047967-300x225.jpg 300w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1141-e1560026047967-768x576.jpg 768w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1141-e1560026047967-350x263.jpg 350w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1141-e1560026047967.jpg 1440w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This display works great with my Raspberry Pi B+ or A+. To get things started I followed the tutorial\/guide on Adafruit\u2019s website&nbsp;<a href=\"https:\/\/learn.adafruit.com\/adafruit-2-2-pitft-hat-320-240-primary-display-for-raspberry-pi\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>. I\u2019ll not go into detail regarding getting the PiTFT working with your Pi as Adafruit covers it very well.<\/p>\n\n\n\n<p>For network\/internet connection I used a Pi-compatable USB wifi dongle, again I\u2019ll not go into detail with&nbsp;installing that, as it differs a great deal depending on what make\/model dongle you get your hands on. There\u2019s tons of stuff on the internet discussing wifi dongles with the Raspberry Pi.&nbsp;Also you&nbsp;could always just use an ethernet cable.<\/p>\n\n\n\n<p>Once you get your PiTFT display working with the example code from Adafruit, there\u2019s only a few steps to take to turn your new display into a stock ticker.<\/p>\n\n\n\n<p>Install pygame. It\u2019s usually installed as standard with Raspbian. You can check by running Python at the command line, then the following at the interactive shell:<br \/><code>&gt;&gt;&gt; import pygame<\/code><br \/>If nothing happens then you already have pygame installed, else you\u2019ll get an error like:<br \/><code>ImportError: No module named pygame<\/code><br \/>If it isn\u2019t installed, then quit Python and do a:<br \/><code>$ sudo apt-get install python-pygame<\/code><\/p>\n\n\n\n<p>Next we need to install Yahoo\u2019s API \u201cystockquote\u201d, at the console:<br \/><code>$ pip install ystockquote<\/code><\/p>\n\n\n\n<p>There is plenty of example code&nbsp;<a href=\"https:\/\/pypi.python.org\/pypi\/ystockquote\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>&nbsp;on Python\u2019s website if you want to have a mess about, or see how it can be used.<\/p>\n\n\n\n<p>I used a font from www.dafont.com called \u201cCodeNewRoman b\u201d, you can download that&nbsp;<a href=\"http:\/\/www.dafont.com\/code-new-roman.font\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>. Copy the font file into the same place as the Python script.<\/p>\n\n\n\n<p>Now it\u2019s just a case of saving and running the Python script below:<br \/><code>$ python PiStockTFT.py<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env python\nimport os\nimport time\nimport socket\nimport pygame\nimport ystockquote\ndef main():\n    #Colours\n    WHITE = (255,255,255)\n    GREY = (240,240,240)\n    BLACK = (0,0,0)\n    BLUE = (0,145,255)\n    RED = (255,0,0)\n    GREEN = (0,255,0)\n    YELLOW = (255,255,0)\n    tickersymbols = ['LWRF.L','BTG.L','AAPL','AUE.L']\n    print(\"\\n============================================\")\n    print(\"= StockPi stock ticker from www.warmcat.uk =\")\n    print(\"============================================\\n\")\n    print(\"Initialising TFT...\")\n    os.putenv('SDL_FBDEV', '\/dev\/fb1')\n    pygame.init()\n    pygame.mouse.set_visible(False)\n    lcd = pygame.display.set_mode((320,240))\n    lcd.fill(BLACK)\n    pygame.display.update()\n    myfont = pygame.font.Font(\"CodeNewRoman_b.otf\", 32)\n    myfont2 = pygame.font.Font(\"CodeNewRoman_b.otf\", 24)\n    keep_running = True\n    try:\n        textToPrint = myfont.render(\"Fetching data...\", 0, WHITE)\n        lcd.blit(textToPrint, (10,210))\n        pygame.display.update()\n        while keep_running:\n            x = 0\n            pygame.draw.circle(lcd, YELLOW, (307,12), 6, 0)\n            pygame.display.update()\n            print(\"Fetching data...\")\n            for tickerSymbol in tickersymbols:\n                try:\n                    allInfo = ystockquote.get_all(tickerSymbol)\n                except:\n                    textToPrint = myfont.render(\"Error...\", 0, WHITE)\n                    lcd.blit(textToPrint, (10,210))\n                    pygame.display.update()\n                    print(\"Connection Error, waiting 20 seconds.\")\n                    time.sleep(20)\n                    pass\n                price = float(allInfo[\"price\"])\n                change = float(allInfo[\"change\"])\n                percent = change\/(change + price)*100\n                peratio = allInfo[\"price_earnings_ratio\"]\n                if change == 0:\n                    ourColour = GREY\n                elif change &gt; 0:\n                    ourColour = GREEN\n                else:\n                    ourColour = RED\n                print tickerSymbol + \"\\t= %3.2f (%+0.2f, %+0.2f%%) P\/E %s\" % (price, change, percent, peratio)\n                stockPrice = (\"{:&gt;6.2f}\".format(price))\n                stockChanges = (\"({:&gt;+5.2f}, {:&gt;+5.2f}%)\".format(change, percent))\n                if x == 0:\n                    lcd.fill(BLACK)\n                textToPrint = myfont.render(tickerSymbol, 0, WHITE)\n                lcd.blit(textToPrint, (30,7+x))\n                textToPrint = myfont.render(stockPrice, 0, ourColour)\n                lcd.blit(textToPrint, (160,5+x))\n                textToPrint = myfont2.render(stockChanges, 0, ourColour)\n                lcd.blit(textToPrint, (62,32+x))\n                x=x+58;\n            pygame.display.update()\n            print(\"Done.\")\n            time.sleep(60) #seconds (so every 1 min)\n    except KeyboardInterrupt:\n        print(\"\\nQuitting...\")\n        keep_running = False\n    else:\n        print(\"Oh my god, it's all gone to shit!\")\n        lcd.fill(BLACK)\n        textToPrint = myfont.render(\"ERROR...\", 0, WHITE)\n        lcd.blit(textToPrint, (10,210))\n        pygame.display.update()\n        raise\nif __name__ == '__main__': main()<\/code><\/pre>\n\n\n\n<p>Here&#8217;s how it looks:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"http:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_0114-1-e1560026493235.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"766\" src=\"http:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_0114-1-e1560026493235-1024x766.jpg\" alt=\"\" class=\"wp-image-365\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_0114-1-e1560026493235-1024x766.jpg 1024w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_0114-1-e1560026493235-300x225.jpg 300w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_0114-1-e1560026493235-768x575.jpg 768w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_0114-1-e1560026493235-350x262.jpg 350w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_0114-1-e1560026493235.jpg 1216w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I also used the same type of display for a train map project utilising the National Rail API, but alas did not document it:<\/p>\n\n\n\n<figure class=\"wp-block-gallery columns-2 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\"><ul class=\"blocks-gallery-grid\"><li class=\"blocks-gallery-item\"><figure><a href=\"http:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1154-1024x768.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"http:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1154-1024x768.jpg\" alt=\"\" data-id=\"367\" data-link=\"http:\/\/warmcat.uk\/?attachment_id=367\" class=\"wp-image-367\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1154-1024x768.jpg 1024w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1154-300x225.jpg 300w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1154-768x576.jpg 768w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1154-350x263.jpg 350w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><a href=\"http:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1311-1024x768.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"http:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1311-1024x768.jpg\" alt=\"\" data-id=\"368\" data-link=\"http:\/\/warmcat.uk\/?attachment_id=368\" class=\"wp-image-368\" srcset=\"https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1311-1024x768.jpg 1024w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1311-300x225.jpg 300w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1311-768x576.jpg 768w, https:\/\/warmcat.uk\/wp-content\/uploads\/2019\/06\/IMG_1311-350x263.jpg 350w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure><\/li><\/ul><\/figure>\n","protected":false},"excerpt":{"rendered":"<p class=\"excerpt\">UPDATE: Yahoo\u2019s ystockquote is no longer available. However one person emailed me advising that it\u2019s still possible to obtain Yahoo\u2019s stock by parsing data with the python package \u201cBeautifulSoup\u201d. I&hellip; <span class=\"more-link\">more<\/span><\/p>\n","protected":false},"author":3,"featured_media":365,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[39,69],"tags":[49,43,71,101,107],"class_list":["post-362","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-electronics","category-raspberry-pi","tag-display","tag-electronics-2","tag-lcd","tag-raspberry-pi","tag-stock-ticker"],"_links":{"self":[{"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/posts\/362","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=362"}],"version-history":[{"count":4,"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/posts\/362\/revisions"}],"predecessor-version":[{"id":394,"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/posts\/362\/revisions\/394"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=\/wp\/v2\/media\/365"}],"wp:attachment":[{"href":"https:\/\/warmcat.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=362"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=362"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/warmcat.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=362"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}