Shipping PyStonks v2 with a friend 🐷

Shipping PyStonks v2 with a friend 🐷

September 11, 2025

Tl;DR

The historical stock webapp, companion for: https://financeinmotion.fyi

+++ People are doing the classic bait: I finally reach xyz divs a year On reddit with a snapshot of a web app to get traction.

+++ More and cooler yfinance for a ~PyStocks v2

Intro

To pull data from yfinance should not be a secret anymore:

Plus also on the initial PyStonks Post, I dedicted time for a yfinance EDA ipynb section.

Bc https://nbformat.readthedocs.io/en/latest/ are great

On my recent pystonks version, I could see how the FastAPI version es more flexible than the PyStocks Streamlit and understandable by LLMs more than Reflex.

While playing very well with SSGs like Astro, unlike Flask or Django.

Now, Im going to take back the collaboration with my friend: btw, he is a PDH.

The Data Model

Even before that: what does this app reply to?

Top Priority:

  1. Historical Prices of stocks: not only NYSE or NASDAQ, but also companies which are listed in other markets, like Nestle, Unilever or MunichRe
  2. Historical Dividends

Lift and coast vs DRIP vs DRIP + invest

Nice to have: 3. Volatility, MDD 4. Historical EPS, PER and Dividend Payout 4. Current (and near history) net profit margin 5. Currency historical exchange rates (EUR<->USD) 6. Inflation Data 7. Bring your portfolio 8. provide for your Portfolio the: historical dividends, confirmed dividends, forecasted dividends (per month/year) 9. Comparison on a stock/portfolio with a sector: https://finance.yahoo.com/sectors/real-estate/ 10. https://millennialmoney.com/calculators/fire-calculator/ 11. https://totalrealreturns.com/s/SCHD,VYM,PEP?start=2020-04-23 12. https://stockanalysis.com/stocks/pep/dividend/ 13. https://fullratio.com/stocks/nyse-ko/coca-cola 14. Buyback ratio (if historical, even better) 15. Volatility div growth mdd cagr / Yfinance eur usd?

Wait, the oil is at the same price than 2006 but i pay more for it? https://www.macrotrends.net/2483/brent-crude-oil-price-history

https://www.gurufocus.com/term/forward-pe-ratio/PEP

See the BRD where we scoped the project.


Conclusions

If you need a proper finance tool, see: https://www.perplexity.ai/finance/XOM?comparing=CVX&period=1y

Before going to https://www.interactivebrokers.ie/sso/Login?RL=1&locale=en_US or https://www.xtb.com/es :)


FAQ

How to define the scope of a Project:

  1. BRD: The high-level business “why” and “what.”
  2. PRD: The detailed product “what.”
  3. FRD: The technical “how.”
FRD vs User Stories 📌

You’ve hit on a key point of the shift from traditional to Agile methodologies.

Yes, in many Agile frameworks, particularly Scrum, user stories often replace the detailed Functional Requirements Document (FRD).

The Problem with the FRD in Agile

  • Fixed and Detailed: The FRD is a static document that assumes all requirements can be known upfront. In Agile, the philosophy is that requirements will emerge and change over time.
  • Discourages Conversation: A comprehensive FRD can lead to a “sign it and build it” mentality, where developers simply follow instructions. Agile values collaboration and communication, and a rigid document can be a barrier to that.
  • Focuses on “What the System Does”: While the FRD is a great tool for technical teams, it can lose sight of the “why.” It describes system behavior (“The system shall validate the user’s credentials”) without tying it to the user’s need.

How User Stories Change the Approach

User stories shift the focus from a detailed technical specification to a high-level, user-centric description. A user story is a promise for a conversation, not a final document.

The classic format of a user story is:

As a <type of user>, I want to <perform some action>, so that <I can achieve some goal/benefit>.

Instead of a 50-page FRD, an Agile team uses a backlog of user stories to define the work.

The Key Elements that Replace the FRD’s Detail

The detailed information that would have been in an FRD doesn’t disappear; it’s just captured differently and at a different time.

  1. Conversation: The user story’s primary purpose is to spark a conversation between the product owner, developers, and designers. This conversation happens during sprint planning and backlog refinement, where the team discusses the “how” in detail.

  2. Acceptance Criteria: Each user story has a set of Acceptance Criteria. These are specific conditions that must be met for the story to be considered “done.” They serve the same purpose as the FRD’s requirements—they define testable system behaviors. For example:

    • User Story: “As a user, I want to be able to log in so that I can access my account.”
    • Acceptance Criteria:
      • GIVEN a user provides a valid email and password, WHEN they click “Log In,” THEN they are redirected to their dashboard.
      • GIVEN a user provides an invalid password, WHEN they click “Log In,” THEN an error message “Invalid credentials” is displayed.
  3. Refinement and Just-in-Time Documentation: The team doesn’t define all the technical details upfront. They are elaborated on as the story moves to the top of the backlog, right before it’s pulled into a sprint. This is often called “just-in-time” documentation.

This avoids building out detailed plans for features that may change or be de-prioritized.

In essence, user stories bring the conversation and collaboration to the forefront, allowing teams to be more flexible and responsive to change—which is the core of the Agile Manifesto.

YFinance Overpowered

Contunuing from the EDA on stonks.

Come on, how cant be possible to get Historical EPS -> PER and Payouts Ratios (div/eps) just with yfinance data?

And get something like: https://www.macrotrends.net/stocks/charts/CL/colgate-palmolive/pe-ratio

All thanks to the ticker.info and Ticker.income_stmt.

See more at this subfolder of the yfinance EDA exploration

import yfinance as yf

ticker = yf.Ticker("MUV2.DE")
info = ticker.info

trailing_pe = info.get("trailingPE", None)
forward_pe = info.get("forwardPE", None)

print(f"Munich Re P/E ratios:")
print(f"Trailing P/E: {trailing_pe} (based on actual earnings over the past 12 months)")
print(f"Forward P/E: {forward_pe} (based on projected earnings over the next 12 months)")

print("\nExplanation:")
print("- The trailing P/E uses the company's historical earnings, providing a reliable snapshot based on actual past performance.")
print("- The forward P/E uses projected future earnings estimates, offering insight into expected growth but subject to forecast uncertainty.")

From the information available about yfinance:

  • For net profit margin: yfinance itself does not provide a direct ready-made field for net profit margin. However, net profit margin can be calculated manually by using net income and total revenue figures, which can be obtained from yfinance financial statements (income statement). The formula is Net Profit Margin = (Net Income / Total Revenue) * 100%. Users would need to extract these figures from yfinance’s income statement data for the company and then compute the ratio externally.[1][2]

  • For historical currency rates: yfinance supports downloading historical forex (currency) price data using ticker symbols for currency pairs. For example, EURUSD=X is a ticker you can query on yfinance to get historical EUR/USD exchange rates, including daily open, high, low, close prices.[3][4]

  • For historical inflation data: yfinance itself does not appear to provide direct historical CPI or inflation rate data as a standard ticker. However, there exist inflation indexes such as IQ CPI Inflation Tracker Index (^IQHGCPI) available on Yahoo Finance, which may be accessible through yfinance for inflation tracking. For detailed inflation data, one might need to use other dedicated economic data sources.[5]

In summary, yfinance can provide the components to calculate net profit margin but not the margin directly, can fetch historical currency exchange rates via forex ticker symbols, and may provide some inflation index tickers but generally not detailed historical inflation rates directly.

It is generally not straightforward to get a long historical series of net profit margins directly from yfinance since yfinance provides only up to about 4 years or 4 quarters of financial statements data (income statement, balance sheet, cash flow). The financials accessible generally show the most recent reported periods.

You can, however, retrieve past annual or quarterly income statements within that limited historical window from yfinance, extract total revenue and net income for each period, and calculate net profit margin manually for those periods.

For longer historical financials data beyond that timeframe, yfinance does not provide it natively. Users often need to rely on more specialized financial databases or services (sometimes paid) or manually collect historical data from annual reports and filings.

In summary:

  • yfinance supports retrieval of recent historical income statements (quarterly/annual) up to about 4 years or 4 quarters.
  • You can parse this data to calculate net profit margins over those recent periods.
  • Long-term historical net profit margin series would require alternative financial data sources outside yfinance.[1][2][3]

How to Start PyStonks Project

Step 1:

Get familiar with git: https://it-tools.tech/git-memo

In this case Github, but it could have been Gitlab / Gitea similarly:

git init
git branch -m main
git config user.name
git config --global user.name "JAlcocerT"
git config --global user.name
git add .
git commit -m "Initial commit: Pystonks Cerdos project"

#sudo apt install gh
gh auth login
gh repo create py-stonks-cerdos --private --source=. --remote=origin --push

Step 2: stop copy pasting from chatgpt and use Windsurf/Cursor/whatever

Are those 20$/month more valuable than your time? Please…

Tests

Ive been doing some branching to do some tests and try how the data layer can look like.

All from the learnings of the previous post.

Firebase Auth

FastAPI x Firebase Auth worked on desktops perfectly:

MailerLite some features behind a subscribe wall could also be interesting

Hoppscotch

When playing/creating APis…

Outo

Interesting concepts:

  1. The compound Interest threshold

Motivational Examples

  1. https://www.dividendcompass.com
  2. https://divstash.app/

People are doing

Interesting cross platform service: https://divstash.app/

I got to know at https://www.reddit.com/r/dividends/comments/1mtpot7/finally_hit_1000_a_year_in_dividends/

With CSR driven Calculate Your Dividend Potential section :)

And has an interesting on boarding flow: https://divstash.app/signup/step-1 and T&Cs are mandatory: https://divstash.app/signup/quick

And by the time of RStocks, I had in mind as reference the stock events app: https://stockevents.app/en?pt=118220498&ct=&mt=8