Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions .github/old_python_publish_yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='stock-analysis-program',
version='1.0.0',
version='1.2.0',
packages=find_packages(),
include_package_data=True,
description='A Python-based toolkit for fetching and visualizing financial data and metrics for stocks.',
Expand Down
70 changes: 70 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: CI

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: Test Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"

- name: Install Poetry
run: |
python -m pip install --upgrade pip
python -m pip install poetry

- name: Validate package metadata
run: poetry check

- name: Install dependencies
run: poetry install --with dev

- name: Run tests
run: poetry run pytest -q

build:
name: Build package
runs-on: ubuntu-latest
needs: test

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "latest"
cache: "pip"

- name: Install build tooling
run: |
python -m pip install --upgrade pip
python -m pip install poetry twine

- name: Build distributions
run: poetry build

- name: Check distributions
run: twine check dist/*
17 changes: 8 additions & 9 deletions .github/workflows/jekyll-gh-pages.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,43 @@
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
name: Deploy Docs to GitHub Pages

on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]
paths:
- "README.md"
- "docs/**"
- ".github/workflows/jekyll-gh-pages.yml"

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./
destination: ./_site

- name: Upload artifact
uses: actions/upload-pages-artifact@v3

# Deployment job
deploy:
environment:
name: github-pages
Expand Down
66 changes: 44 additions & 22 deletions .github/workflows/python_publish.yml
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
name: Upload Python Package
name: Publish Python Package

on:
push:
tags:
- 'v*'
- "v*"
workflow_dispatch:

permissions:
contents: read

jobs:
deploy:
publish:
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/stock-analysis-program/

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Install Poetry
run: |
pip install --upgrade pip
pip install poetry

- name: Build and publish to PyPI
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
run: |
poetry config virtualenvs.create false
poetry build
poetry publish
- name: Checkout
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "latest"
cache: "pip"

- name: Install release tooling
run: |
python -m pip install --upgrade pip
python -m pip install poetry twine

- name: Validate package metadata
run: poetry check

- name: Install dependencies
run: poetry install --with dev

- name: Run tests
run: poetry run pytest -q

- name: Build distributions
run: poetry build

- name: Check distributions
run: twine check dist/*

- name: Publish to PyPI
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
run: poetry publish
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,4 @@ $RECYCLE.BIN/

.vscode/
archive/
pytest-cache-files-*/
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ The Stock Analysis Program is a Python-based toolkit designed to fetch and visua

## Installation

To use this program, ensure you have Python installed on your system. Clone this repository and install the required dependencies:
Install the package from PyPI:

```bash
git clone https://github.com/visionary-code-works/stock-analysis-program.git
cd stock-analysis-program
pip install -r requirements.txt
pip install stock-analysis-program
```

The package also installs a small command-line menu:

```bash
stock-analysis
```

## Usage
Expand All @@ -46,13 +50,24 @@ The program consists of multiple Python classes categorized into Fetchers and Pl
### Example

```python
from plotter.stock_price_plotter import StockPricePlotter
from stock_analysis_program import StockPricePlotter

# Plotting stock prices for Apple and Microsoft
price_plotter = StockPricePlotter(['AAPL', 'MSFT'])
price_plotter.plot_closing_prices('2021-01-01', '2021-12-31')
```

Plotter methods return Matplotlib figure and axes objects for notebook,
testing, or dashboard usage:

```python
figures = price_plotter.plot_closing_prices(
'2021-01-01',
'2021-12-31',
show=False,
)
```

## Documentation

For detailed documentation on each component, please refer to the `docs` directory.
Expand Down
10 changes: 10 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## v1.2.0

- Added the `stock-analysis` console command through the package metadata.
- Moved CLI behavior into `stock_analysis_program.cli` and kept root `main.py` as a compatibility wrapper.
- Standardized public imports around `stock_analysis_program`.
- Updated plotter methods to return Matplotlib figure/axes objects and support `show=False`.
- Added ticker normalization and clearer empty-data validation for fetchers and plotters.
- Replaced network-dependent tests with mocked provider tests.
- Updated README and documentation examples for PyPI installation and package imports.

To rewrite the provided code as a set of classes, we need to organize the functionalities into logical units that represent distinct aspects of the operations. The code you provided contains various functions for fetching and analyzing stock data using the `yfinance` library. Here's how we can organize these functionalities into classes:

1. **StockAveragesFetcher**: Handles the fetching and calculation of moving averages and average trading volume for a single stock ticker.
Expand Down
7 changes: 3 additions & 4 deletions docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ flowchart LR
Each fetcher class can be used independently to retrieve specific data. For example:

```python
from fetcher.stock_summary_fetcher import StockSummaryFetcher
from stock_analysis_program import StockSummaryFetcher

# Fetching stock summaries
summary_fetcher = StockSummaryFetcher(['AAPL', 'MSFT'])
Expand All @@ -93,7 +93,7 @@ print(summaries)
Plotters are used for visualizing data. They often depend on fetchers to get the necessary data. For example:

```python
from plotter.stock_price_plotter import StockPricePlotter
from stock_analysis_program import StockPricePlotter

# Plotting stock prices
price_plotter = StockPricePlotter(['AAPL', 'MSFT'])
Expand Down Expand Up @@ -121,8 +121,7 @@ To extend the program:
Here's an example of how to integrate multiple components in a larger program:

```python
from fetcher.revenue_growth_fetcher import RevenueGrowthFetcher
from plotter.revenue_growth_plotter import RevenueGrowthPlotter
from stock_analysis_program import RevenueGrowthFetcher, RevenueGrowthPlotter

def plot_revenue_growth(tickers):
# Fetching revenue growth
Expand Down
Loading
Loading