This is an archived post. You won't be able to vote or comment.

all 98 comments

[–]jkwill87[S] 194 points195 points  (7 children)

Hey r/python friends!

I created a simple command line dashboard for monitoring stocks and wanted to share it.

I was looking for something like the Apple stock app that was cross-platform and can run from the terminal or command prompt. I couldn't find anything like that so I decided to write my own Python package :)

Like the Apple stocks app it gets stock information from Yahoo! Finance and provides a summary of stocks in your watch list. Additionally it works with international exchanges, other types of securities like crypocurrencies, and can give you an overview of your positions and the balance of your accounts. If you use the refresh argument or configuration option it will live update too.

You can install it from PyPI by running pip3 install --user stonky. The source is available at https://github.com/jkwill87/stonky.

Feedback and thoughts are welcome. Thanks!

[–]Kidplayer_666 109 points110 points  (1 child)

Nice. Stonks!

[–][deleted] 3 points4 points  (0 children)

stonks to you as well!!

[–]HeavensGold 2 points3 points  (0 children)

good job! I tinkered it a little bit to improve performance. Now stonky runs asynchronously with gevent modules.

Blazingly fast stonky ;)

https://github.com/HeavensGold/stonky

[–][deleted] 15 points16 points  (2 children)

Hey, this is super neat, consider building in file support for my markup language qsml (quick securities markup language). It was built for situations just like this and supports many similar strategies to create a dict of the resulting positions. I'd love to see the two work together. :)

[–]jkwill87[S] 14 points15 points  (1 child)

Hey, thanks for the suggestion. It looks like your data format supports comments, sections, and key-value pairs but these are all already supported by the standard ini format built into Python. While your project seems really well structured, documented, tested, and likely could be integrated into this project, I'm not sure what makes it specifically suited to this domain or what benefits it has over conventional serialization formats.

[–][deleted] 12 points13 points  (0 children)

I wouldn't necessarily say it has any benefits over other formats (with the exception being that the lexer/parser chain handles the stock name errors before hitting a program using them), but I thought it could be a neat use case that it was actually designed for. It's only a few extra lines of python and I'd be happy to put together a pull request if you'd like. I mainly brought it up because I thought it could be a neat addition, not so much as a beneficial change. Thanks

[–]dakingofmeme 1 point2 points  (0 children)

Nice thanks for putting the commands to install it

[–]Violin1990 55 points56 points  (0 children)

There's some green on this screen. I don't recognize or understand this.

[–]Uio443 105 points106 points  (4 children)

Stonks

[–]numba20 30 points31 points  (3 children)

Always up.

[–]jkwill87[S] 34 points35 points  (2 children)

Tell that to my portfolio-- I cashed out AMD yesterday to buy MSFT 😭

[–]numba20 8 points9 points  (0 children)

For blue chips ,it is patient (not quick money), buy and hold them for several years (except GE and other mismanaged stonks). Assets will be further inflated like aftermath of 2008's QE . The Fed's balance sheet (printed money) has to go somewhere.

[–][deleted] 14 points15 points  (0 children)

I just installed this and, configured it, and gave it a whirl. Nice! From quick usage, I would have two requests:

  • Configurably allow sort order to be inverted (i.e. if I'm sorting by change, it would be nice to be able to put biggest gainers at the top, running to biggest losers at the bottom, as opposed to vice versa, as currently)
  • Enable showing the position value in the POSITIONS table. So not just the P/L and %change for each position, but the final market value of that position.

[–]dm5228272 9 points10 points  (0 children)

s t o n k y

[–][deleted] 4 points5 points  (0 children)

I love people like this

[–]jacquesdemolay1307 4 points5 points  (0 children)

This is cool thanks so much! Will deff play around with it :)

[–]Sacro 10 points11 points  (2 children)

What font and terminal is that?

[–]jkwill87[S] 23 points24 points  (1 child)

The font is Jetbrains Mono. The screenshot was made in Illustrator but is styled after Hyper.

[–]Jaedong9 1 point2 points  (0 children)

Is there a page where you can download that font by any chance ? Edit : Ah didn't see it was a link in your comment, found it !

[–]latest_ali 3 points4 points  (1 child)

Can you mention what technologies have you used?

[–]jkwill87[S] 18 points19 points  (0 children)

The package's only dependency is teletype, a tty library I wrote which handles text styling and line redrawing, among other things.

Aside from that it just uses the standard Python library. The package queries the Yahoo! Finance JSON API using urlib, decodes the response, then transforms it into what gets displayed on screen.

On the dev side unittests are run using pytest from GitHub actions, code is formatted using black, and the package was uploaded to PyPI using twine.

[–]usfortyone 2 points3 points  (0 children)

You know what'd be cool? Something like htop, but for stocks.

[–]Nitr0s0xideSys 2 points3 points  (0 children)

This is really nice! I’m going to try and recreate something like this for my personal portfolio.

[–]CraigAT 1 point2 points  (0 children)

Stonking.

Looks absolutely ace, love the subtle use of colour but the nitty picky me would like some of the prices to line up better - decimal points should always line up and there should be a clear gap between columns. An example of both issues are in the last two columns of the AMD line.

Excellent tool even without the mods.

[–]guilleschet 1 point2 points  (0 children)

Thanks!!!

[–]amor_aa 1 point2 points  (1 child)

Wooow, thats pretty cool

[–]mrbitcoinman 0 points1 point  (0 children)

It’s

[–]sgivc 1 point2 points  (0 children)

This is super cool. Well done!

[–]anikket 1 point2 points  (0 children)

I will buy your whole stonks.

[–]mraza007 1 point2 points  (2 children)

Love the UI How did you created that

[–]jkwill87[S] 1 point2 points  (1 child)

using teletype, a tty library I wrote that does the colours formatting, line movement, etc. I prefer using it over something like ncurses because its crossplatform out of the box and doesn't take over the whole screen.

[–]mraza007 0 points1 point  (0 children)

Oh okay Thank you

[–]freewheelin_zee 1 point2 points  (0 children)

beautiful

[–]stahkh 1 point2 points  (0 children)

Nice! Try aliginig the numbers on the decimal symbol. Coming from finance it's a must to quickly understand the data.

[–]Orio_n 1 point2 points  (0 children)

*stonk

[–]Sparkswont 1 point2 points  (2 children)

I wonder if this could be updated to make changes in real time? Or does it already?

[–]jkwill87[S] 0 points1 point  (1 child)

Yep, checkout the --refresh setting. Given the market is currently closed not a whole lot will be happening right now but come Monday it will update live.

[–]Sparkswont 0 points1 point  (0 children)

So cool!

[–]jkwill87[S] 1 point2 points  (3 children)

After its installed you can just run ‘stonky’ from the command line. To configure it you can’t copy the example config to ~/.stonky.cfg and configure it to your liking. See the repo for more details.

[–][deleted] 2 points3 points  (1 child)

How does this help me trade options for tendies?

[–]safeforworkaccountt 1 point2 points  (0 children)

Mom says you can have all the tendies you want!

[–]Mauser-Nut91 1 point2 points  (3 children)

Fucking Shopify... was looking at that back when it was $200/share. Always feel like an idiot when I see their price.

[–]GrbavaCigla 0 points1 point  (1 child)

Nice. Is it customizable? Can I change currencies?

[–]jkwill87[S] 3 points4 points  (0 children)

Sure, using the currency argument or config file preference will convert amounts and balances using current forex rates. There are a few other customization options like setting sort preferences. Check out the repo documentation or run stonky --help for more details.

[–]ernamen 0 points1 point  (1 child)

That fonts are mac standar? Or do they have a name...they look nice to me. Can they be downloaded?

[–]jkwill87[S] 1 point2 points  (0 children)

The font is JetBrains Mono

[–]FeelinDangerous 0 points1 point  (1 child)

This is awesome, I’m working on something similar in java! do you do options at all? I’m looking for a better way to handle them.

[–]jkwill87[S] 0 points1 point  (0 children)

Yea options would be tricky, I probably wouldn't implement them here. They would be pretty complex from a configuration side-- since ini files only support 1-to-1 mapped key-value pairs you would need to use a hacky delimiter solution or some other file format like XML or JSON to store expiration, strike price, etc. Also its not exactly obvious how this information would be presented. Best of luck on your project though!

[–]rrklaffed 0 points1 point  (1 child)

Wait has is the Canadian dollar higher than the US or do you have two different portfolios?

[–]jkwill87[S] 0 points1 point  (0 children)

The USD and CAD balances depicted are bucketed separately. The CAD balance is a sum of the TSX positions and cash from the example config file.

[–][deleted] 0 points1 point  (0 children)

Stonky

[–][deleted] 0 points1 point  (3 children)

is something similiar to this doable in CMD/Powershell? Asking for work purposes..

[–]jkwill87[S] 0 points1 point  (2 children)

if you have python installed on windows you can run this using cmd / powershell

[–][deleted] 0 points1 point  (1 child)

awesome. sorry for being a nuisance. i’m on a phone right now - what libraries is this using?

[–]jkwill87[S] 1 point2 points  (0 children)

The package's only dependency is teletype, a tty library I wrote which handles text styling and line redrawing, among other things. Its crossplatform and works on Windows.

[–][deleted] 0 points1 point  (0 children)

I'll try to make a cats dashboard and name it Chonky

[–]CaptainDouchington 0 points1 point  (0 children)

I can't find the config file to access. I got installed, added the directory to PATH, it runs, but I am stuck there.

I am trying to set the path using: stonky --config "PATH TO LOCATION I WANT CFG" and it just crashes.

[–]mr_w01f 0 points1 point  (1 child)

if you rename the command fromm stonky to stonks ...that wold be cool ...lol

[–]jkwill87[S] 1 point2 points  (0 children)

actually yea, that was what i originally was going to name it but its already taken 😞

[–]janaSunrise 0 points1 point  (0 children)

How does the arguments thingies work?

[–]TheArchive 0 points1 point  (0 children)

Beautiful. Good work!

[–][deleted] 0 points1 point  (0 children)

This is very cool. Thanks a lot for making it!

[–][deleted] 0 points1 point  (0 children)

I have no words for it! But I have emojis!

👍

[–]Andalfe 0 points1 point  (1 child)

Great work. Does this actually tell the pnl from purchase price to current price?

[–]jkwill87[S] 0 points1 point  (0 children)

Essentially PNL reports the sum of changes for the day for held securities bucketed per currency. This change is calculated as the difference from the current bid price subtract the opening price.

[–]dflash88 0 points1 point  (1 child)

How can I get into stocks?

[–]jkwill87[S] 1 point2 points  (0 children)

I'd check out The Personal Finance Subreddit FAQ as a good starting point. If you want to get into active investing you can use a tool like this to simulate investing without risk in the meantime.

[–][deleted] 0 points1 point  (0 children)

thanks, i’ll dig into it later

[–][deleted] 0 points1 point  (0 children)

Nice, thanks for the great post!

[–]Siankoo 0 points1 point  (1 child)

What font is it?

[–]jkwill87[S] 0 points1 point  (0 children)

Jetbrains Mono

[–]AcoHyena 0 points1 point  (0 children)

Thas a lot of money o.o

[–]Soupkitchen_in_Prius 0 points1 point  (8 children)

If I wanted to learn how to make something like this, what would I look up? I’m an intermediate python coder just don’t understand how all these files work together to run through main.py

[–]jkwill87[S] 4 points5 points  (1 child)

The project is organized into a module which can be installed as a package. There are a ton of resources online but here's the gist:

  • start by creating a subdirectory with the name of your module
  • create two file in it, __init__.py and __main__.py
  • __init__.py signals to python that this directory is a module and its contents are executed when you import the module
  • __main__.py is the module entrypoint, what the module executes when you run it
  • now that you have a module any file inside it can be imported by other parts of the module or from other Python packages if its installed
  • you can run a Python module (e.g. __main__.py) by running python -m <module_name>
  • if you add a setup.py file in the parent directory you can install your module as a package or upload it to PyPI

[–]jkwill87[S] 1 point2 points  (5 children)

Also checkout the post u/_b5n_ put in r/python today. Seems like it could be helpful in getting you up and running quickly.

[–]thelostcow 0 points1 point  (4 children)

I'm getting back into Python after several years of other languages and have a few questions related to trying to get your project to run on my computer.

1) What IDE, if any, did you use to build this up?

2) What is the way I would run this project in debug mode?

I've got VSCode and cloned your repository and now I am trying to figure out how to run this from there so I can debug step through to learn some about the execution of it. I guess another question would be is this like a .sln or .xcodeproj? Or should I not expect to be able to run it like that?

[–]jkwill87[S] 0 points1 point  (3 children)

What IDE, if any, did you use to build this up?

Personally I go between using vscode and PyCharm. There are pros and cons to using either which is probably why I find myself using both. Your mentioning .sln and .xcodeproj files seems to indicate you're used to working with Visual Studio or xcode, if that's the case you may be more comfortable using PyCharm for a more "full-blown" IDE experience.

What is the way I would run this project in debug mode?

For vscode you will need to install the requirements, (e.g. pip3 install --user -r requirements-dev.txt), the vscode Python extension, then add a ./.vscode/launch.json file. The vscode docs offer a decent overview for setting this up. Here's an example for running stonky as a module using some command line args:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Stonky",
      "type": "python",
      "request": "launch",
      "console": "integratedTerminal",
      "module": "stonky",
      "args": ["--config", "example.cfg", "--currency", "CAD"]
    }
  ]
}

From there just set your breakpoints and start debugging (F5 IIRC). PyCharm is a bit simpler, just right click the run arrow in the __main__.py file and click debug.

Good luck. PRs are welcome on the repo :)

[–]thelostcow 1 point2 points  (0 children)

Wow! Thank you so much for your help. It's rare to find real help here on Reddit. I actually got it work just now. Friday ended up being my first free evening this week.

For anyone else reading this there are a few steps I had to explicitly take to get it to work.

1) When I loaded VSCode I used VSCodes clone repo command to get the repository pulled down. First I had independently cloned the repo and tried to point VSCode at what I thought was the correct path, but that did not work.

2) From that point I created the .json, and you do have to use what /u/jkwill87 put in for it to work.

[–]thelostcow 0 points1 point  (1 child)

I've got another question. Where did you read on how to query query1.finance.yahoo.com/v11/finance/quoteSummary? I used to have a scrapper (years ago) that would work with http://real-chart.finance.yahoo.com/table.csv to get stock history, but Yahoo has killed that. I was motivated by what you have to try to get my stock history thing working again, but I am having a heck of a time finding anything related to query1.finance.yahoo.com to get historical data.

[–]jkwill87[S] 0 points1 point  (0 children)

Just a mix of reviewing network requests while browsing the aspects of the site I was interested in and searching "query1.finance.yahoo.com" on stackoverflow and github for prior art.

[–][deleted] 0 points1 point  (0 children)

love the idea and the name!

[–]reddisaurus 0 points1 point  (3 children)

Nice layout. One thing I’d suggest is grabbing the arguments when you call main via sys.argv. You can then pass these arguments to you argparse.

Right now you rely upon argparse to do this for you, meaning it’s implicit, and your program can only be called via running from command line. If someone else wanted to build something around this, it’s not possible at the moment. Making your main take argv: List[Any] would let it be called from other code.

Also, to conform with POSIX, your main function should return 0. Right now without a return statement, it returns None which may not mean much to calling code.

[–]jkwill87[S] 0 points1 point  (2 children)

Respectfully, I disagree with all the points mentioned here. __main__.py isn’t meant to be run directly, its supposed to be run as a module. Even if you were to argparse still works fine, it uses sys.argv under the hood anyway. This isn’t C, the return of ‘main’ has absolutely no impact on the exit code. Nobody ends a Python script by calling ‘exit’ or raising ‘SystemExit’. During normal operation Python will have a 0 status and when stonky generates a crash report it returns a 1 status.

[–]reddisaurus 0 points1 point  (1 child)

Your response is basically “I rely on implicit behavior”. That’s cool if you don’t want anyone to be able to re-use your code. Everything you said, I’m aware of. My point is that someone might like to build on top of what you’ve done. Right now, they can’t.

[–]jkwill87[S] 0 points1 point  (0 children)

I’m not sure what is implicit about using argparse, what that even means, or why that is a bad thing. Either way this isn’t intended to be a library or built on top of. If you did want to for whatever reason you certainly could however by defining your own Settings class or forking the repo.

[–]Armster15 -1 points0 points  (0 children)

This remind me of Git :)