Levi DeHaan

Stock Transcript CLI (Ticker2Txt) - Human-Readable Stock Analysis

Python CLI application that transforms intraday price bars into time-stamped, human-readable transcripts with peak/valley detection using SciPy, interactive TUI with Rich and prompt-toolkit, and optional news sentiment integration.

Status: completed · 2025-04-01

Overview

The Stock Transcript CLI (Ticker2Txt) fetches intraday OHLCV data from Financial Modeling Prep, resamples it into custom intervals, detects peaks and valleys using SciPy, and generates human-readable transcripts. Features an interactive TUI with Rich styling, batch CLI mode, report saving, configuration persistence, and optional news sentiment analysis with comprehensive API endpoints.

Technologies

Python 3.9+, Rich, prompt-toolkit, Pandas, SciPy, Requests, Financial Modeling Prep API, DataFrame Resampling, Signal Processing, Peak Detection, Valley Detection, Text Generation, YAML Configuration, Command Line Interface, Interactive TUI, Report Generation, Config Persistence, News Sentiment Analysis, API Integration, Batch Processing, Markdown Export, Pure Python, Real-time Data, Intraday Analysis, Financial Data Processing

Interval Support
1-30 Minutes
Peak Detection
SciPy-based
Report Formats
Text/Markdown
API Integration
FMP News Sentiment

The Stock Transcript CLI turns raw intraday price bars from Financial Modeling Prep (FMP) into a time-stamped, human-readable diary of every rise, dip, peak, and valley. It resamples arbitrary intervals (e.g., 7-minute windows), highlights significant highs/lows with SciPy's peak-detection, and lets you read the story in the terminal or save it as a text/Markdown report. A Rich + prompt-toolkit interface makes the workflow feel like a modern TUI app.

Below you'll find a production-ready README.md—drop it in your project root and you're good to go.


Overview

`stock_transcript_cli.py` fetches intraday OHLCV data through FMP's historical-chart endpoint (Free Stock Market API and Financial Statements API... | FMP), groups it with Pandas `DataFrame.resample` (pandas.DataFrame.resample — pandas 2.2.3 documentation), detects peaks via `scipy.signal.find_peaks` (find_peaks — SciPy v1.15.2 Manual), and renders a plain-English transcript using Rich's styling (Console API — Rich 13.6.0 documentation). prompt-toolkit powers interactive menus, autocompletion, and confirmation prompts (Python Prompt Toolkit 3.0 — prompt_toolkit 3.0.50 documentation).


Features

  • Minute-level to custom interval summaries – any bucket size you choose (1, 5, 7, 15 min, etc.)
  • Peak / Valley tagging – prominence-based detection with SciPy (find_peaks — SciPy v1.15.2 Manual)
  • Interactive TUI – colourful menus via Rich (rich - PyPI) and prompt-toolkit (Python Prompt Toolkit 3.0 — prompt_toolkit 3.0.50 documentation)
  • Batch CLI mode – run non-interactively for scripts / cron jobs
  • Report saving – writes `.txt` or `.md` files to `reports/`
  • Config persistence – remembers last-used parameters in `~/.stock_transcript.yml`
  • MIT-licensed & pure-Python (3.9+) – no C extensions

Installation

```bash python -m pip install requests pandas scipy rich prompt_toolkit ```

All dependencies are hosted on PyPI (rich - PyPI, Requests - PyPI).


Quick-start

```bash

1. Export your FMP key (free tier available)

export FMP_API_KEY="YOUR_KEY"

2. Launch the TUI

python stock_transcript_cli.py ```

The menu will ask for:

  1. Ticker (e.g., `AAPL`)
  2. Source interval – FMP supports 1, 5, 15 & 30 min bars (Free Stock Market API and Financial Statements API... | FMP)
  3. Bucket size – how many minutes per summary line
  4. Optional date range (`YYYY-MM-DD`)

Read the live transcript or press Y to save a report.


Command-line usage

```bash python stock_transcript_cli.py \ --symbol AAPL \ --from 2025-04-24 --to 2025-04-25 \ --interval 1min \ --bucket 7 \ --output reports/aapl_7m.txt ```

FlagPurpose
`--symbol`Ticker symbol (required)
`--from / --to`Date range (inclusive, ISO-8601)
`--interval`Source bars in FMP (`1min`, `5min`, …)
`--bucket`Minutes per transcript line
`--output`Path for the saved report (optional)

How it works

1 . Data retrieval

`requests` pulls JSON from `.../historical-chart/{interval}/{symbol}` (Free Stock Market API and Financial Statements API... | FMP). API bandwidth limits apply on free keys (FAQs - Financial Modeling Prep API | FMP).

2 . Bucketing

Pandas resamples to an n-minute rule, keeping the first open, max high, min low, last close, and summed volume (pandas.DataFrame.resample — pandas 2.2.3 documentation).

3 . Peak detection

SciPy compares each point with its neighbours; a prominence default of 5 % median price filters noise (find_peaks — SciPy v1.15.2 Manual).

4 . Narrative generation

For each bucket:

  • Positive Δ → "went up by $X"
  • Negative Δ → "went down by $X"
  • Peak / valley flags insert special sentences.

Rich colourises output; tables of parameters can be added with `rich.table` (Console API — Rich 13.6.0 documentation, The terminal formatting library you need in 2022 - DEV Community).


Saving reports

Reports land in `reports/` with a timestamp, or in the path you supply. Each line mirrors the terminal output. Text files open cleanly in editors, spreadsheets, or can be parsed downstream.


Configuration

The first time you run the CLI, it writes a YAML file at `~/.stock_transcript.yml` containing your last-used ticker, dates, and bucket size for convenience.


API limits & data caveats

ConstraintNotes
Free-tier bandwidthFMP throttles high-volume users ([FAQs - Financial Modeling Prep API
Historical depthMinute bars retain ~1 month on free plans; upgrade for more.
Real-time vs delayedData is "as-close-to-real-time" as FMP provides; day-traders may need premium exchanges (Real Time: What It Means Compared to Delayed Quotes)
Market hours awarenessScript prints timestamps in US/Eastern; it does not yet skip overnight gaps.

Development

```bash git clone https://github.com/your-org/stock-transcript-cli.git cd stock-transcript-cli python -m venv venv source venv/bin/activate pip install -r requirements.txt ```

Run lint & tests (add your own):

```bash ruff . pytest ```


Roadmap

  • Parameter for custom peak-detection prominence
  • Skip non-trading hours automatically
  • CSV / Markdown / HTML export
  • Streamlit dashboard

API Endpoints

The application provides several REST API endpoints for news sentiment analysis and stock transcript generation:

News Sentiment Analysis Endpoint

POST `/api/sentiment`

Analyzes sentiment for news articles related to a stock symbol, with comprehensive company information and optional data sources.

Request Body

```json { "ticker": "AAPL", "num_articles": 20, "use_custom_model": false, "include_transcripts": false, "include_press_releases": false, "use_social_sentiment": false } ```

Request Parameters

  • `ticker` (string, required): Stock ticker symbol (e.g., "AAPL", "MSFT")
  • `num_articles` (integer, optional): Number of articles to analyze (1-50, default: 10)
  • `use_custom_model` (boolean, optional): Use custom trained model instead of default (default: false)
  • `include_transcripts` (boolean, optional): Include earnings call transcripts in analysis (default: false)
  • `include_press_releases` (boolean, optional): Include company press releases (default: false)
  • `use_social_sentiment` (boolean, optional): Factor in social media sentiment from StockTwits (default: false)

Response

```json { "ticker": "AAPL", "company_profile": { "companyName": "Apple Inc.", "symbol": "AAPL", "industry": "Consumer Electronics", "sector": "Technology", "description": "Apple Inc. designs, manufactures, and markets...", "website": "https://www.apple.com", "ceo": "Timothy Donald Cook", "employees": 154000, "marketCap": 3000000000000 }, "articles": [ { "title": "Apple Announces New Product Line", "desc": "Apple today announced...", "link": "https://example.com/article", "date": "2025-01-15", "site": "Reuters", "sentiment": "positive", "score": 0.85, "base_score": 0.75, "time_weight": 1.0, "datetime": "2025-01-15T10:30:00Z", "type": "news" } ], "stock_chart": "/static/images/sentiment_AAPL.png", "sentiment_chart": "/static/images/chart_AAPL_20250115.png", "social_sentiment": { "sentiment": 75, "sentimentChange": 5.2, "bullishPercent": 68, "bearishPercent": 32 }, "earnings_data": { "past_earnings": [...], "upcoming_earnings": [...] }, "summary": { "total": 20, "positive": 12, "neutral": 5, "negative": 3, "avg_score": 0.72, "transcript_count": 2, "press_release_count": 1, "news_count": 17 }, "training_data_stats": { "total": 1250, "positive": 420, "neutral": 415, "negative": 415 }, "using_custom_model": false } ```

Stock Transcript Generation Endpoint (Ticker2Txt)

POST `/transcript`

Generates a human-readable transcript of stock price movements with peak/valley detection and optional news integration.

Request Body

```json { "symbol": "AAPL", "from": "2025-01-10", "to": "2025-01-15", "interval": "5min", "news_enabled": true } ```

Request Parameters

  • `symbol` (string, required): Stock ticker symbol (e.g., "AAPL", "MSFT")
  • `from` (string, required): Start date in YYYY-MM-DD format
  • `to` (string, required): End date in YYYY-MM-DD format
  • `interval` (string, optional): Data interval - "1min", "5min", "15min", "30min" (default: "5min")
  • `news_enabled` (boolean, optional): Include relevant news articles in transcript (default: true)

Response

```json [ "2025-01-10 09:30:00 EST: AAPL opened at $185.50", "2025-01-10 09:35:00 EST: Stock went up by $2.30 to $187.80 (volume: 125,000)", "2025-01-10 09:40:00 EST: Stock reached a local peak at $188.45", "2025-01-10 09:45:00 EST: Stock went down by $1.20 to $187.25 (volume: 89,000)", "📰 2025-01-10 09:42:00 EST: News Alert - Apple announces new product line", "2025-01-10 09:50:00 EST: Stock reached a local valley at $186.80", "2025-01-10 09:55:00 EST: Stock went up by $3.15 to $189.95 (volume: 156,000)" ] ```

Historical Analysis Endpoint

GET `/api/history`

Retrieves historical sentiment analysis results with pagination and search capabilities.

Query Parameters

  • `page` (integer, optional): Page number (default: 1)
  • `page_size` (integer, optional): Items per page (default: 10)
  • `search_term` (string, optional): Search by ticker symbol
  • `sort_by` (string, optional): Sort column - "query_date", "ticker", "sentiment_score" (default: "query_date")
  • `sort_dir` (string, optional): Sort direction - "asc" or "desc" (default: "desc")

Response

```json { "items": [ { "id": 123, "ticker": "AAPL", "query_date": "2025-01-15T14:30:00Z", "articles_count": 20, "positive_count": 12, "neutral_count": 5, "negative_count": 3, "sentiment_score": 0.72, "custom_model_used": false, "stock_chart_path": "images/sentiment_AAPL.png" } ], "total": 45, "page": 1, "page_size": 10, "total_pages": 5 } ```

Sentiment Corrections Endpoint

POST `/api/sentiment/save_corrections`

Saves corrected sentiment labels for model training improvement.

Request Body

```json { "articles": [ { "title": "Article title", "text": "Article content...", "sentiment": "positive", "corrected_sentiment": "negative", "ticker": "AAPL" } ] } ```

Model Training Endpoint

POST `/api/sentiment/train_model`

Triggers training of a custom sentiment analysis model using corrected data.

Response

```json { "success": true, "message": "Model training started", "training_id": "train_20250115_143022" } ```

Training Status Endpoint

GET `/api/sentiment/training_status`

Check the status of model training.

Response

```json { "running": false, "status": "completed", "progress": 100, "message": "Training completed successfully", "start_time": "2025-01-15T14:30:22Z", "end_time": "2025-01-15T15:45:18Z", "error": null } ```


References