StockBot automates a weekly value-investing workflow. It fetches financial statements from Yahoo Finance, derives per-share metrics, and scores each holding against eleven weighted criteria covering valuation (P/E, P/B, PEG), quality (ROE, Piotroski), cash flow, and margin-of-safety considerations. Scores drive BUY/HOLD/SELL recommendations that are persisted to PostgreSQL and surfaced via CSV exports and Telegram notifications. The project demonstrates production-grade async database access, typed data pipelines, and lightweight integrations with LLM-based confirmation and news enrichment.
- Eleven-factor scoring model covering value, profitability, and quality metrics.
- Daily ingestion that aggregates into a Monday rebalancing report.
- CSV export suitable for manual execution or brokerage import.
- Optional LLM confirmation stage with OpenAI and Tavily news search.
- Telegram notifications for daily status updates.
- Async PostgreSQL data layer built on psycopg v3.
- Key dependencies include
yfinancefor market data,psycopgfor async database access,openaiandtavily-pythonfor confirmation, andpython-dotenvfor configuration management.
| Factor | Weight |
|---|---|
| Asset Value (P/B vs 1) | 15 % |
| P/E Ratio | 10 % |
| P/B Ratio | 5 % |
| PEG Ratio | 10 % |
| Debt / Equity | 5 % |
| ROE | 10 % |
| Free-Cash-Flow Yield | 10 % |
| Dividend Yield | 5 % |
| Margin of Safety (Intrinsic – Price) | 15 % |
| Peer Relative (EV/EBITDA & P/S) | 10 % |
| Piotroski F-score | 5 % |
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt- Duplicate
.env.exampleas.envand provide the following variables:DB_REMOTE(orDB_DSN): PostgreSQL connection string.WEEKLY_BUDGET: Optional weekly cash contribution (defaults to 50).OPENAI_API_KEY,TAVILY_API_KEY: Required for LLM confirmation.TELEGRAM_BOT_TOKEN,TELEGRAM_CHAT_ID: Required for notifications.
- Ensure PostgreSQL is reachable. Example using Docker:
docker run --name stockbot-db \ -e POSTGRES_USER=stockbot \ -e POSTGRES_PASSWORD=stockpass \ -e POSTGRES_DB=stockbot \ -p 5432:5432 -d postgres:16
- Bootstrap the schema:
python ensure_tables.py
- Seed the starting portfolio by editing
portfolio.csvand running:python init_portfolio/init_portfolio.py
python main.pyThis command performs a weekday-specific ingestion. Monday executions aggregate the previous six daily snapshots, compute average scores, clear the daily tables, send a Telegram summary, and store final decisions in the analysis table.
from llm_confirmer import confirm_decisions
analyses = [
{"ticker": "BMW.DE", "score": 72.5, "decision": "BUY"},
{"ticker": "ENEL.MI", "score": 38.1, "decision": "SELL"},
]
confirmed = confirm_decisions(analyses)from portfolio_manager import plan_trades
from report import write_csv
portfolio = [
{"ticker": "BMW.DE", "quantity": 5.0},
{"ticker": "ENEL.MI", "quantity": 10.0},
]
analyses = [
{"ticker": "BMW.DE", "price": 95.2, "score": 78.4, "llm_decision": "BUY"},
{"ticker": "ENEL.MI", "price": 6.1, "score": 35.0, "llm_decision": "SELL"},
]
sell_plan, buy_plan = plan_trades(portfolio, analyses, base_budget=50.0)
write_csv(sell_plan, buy_plan)This produces a CSV similar to:
Action,Ticker,Quantity,Price,Allocated Amount (€)
SELL,ENEL.MI,10.0,6.1,61.0
BUY,BMW.DE,1,95.2,95.2Run the automated test suite with:
pytest- Database: Host PostgreSQL on a managed service such as Neon or RDS.
- Scheduler: Use a cron service (Render cron jobs, GitHub Actions, or systemd timers) to execute
python main.pyat the desired cadence. - Secrets Management: Provide environment variables through the scheduler or a secrets manager.
Distributed under the MIT License. See LICENSE for details.