Stock Analyst is a FastAPI-based stock research service that uses Google ADK and LiteLLM to analyze a ticker symbol and return a structured research summary. The app combines yfinance market data, VADER sentiment scoring, and an agent-driven workflow to deliver a concise analysis with a buy/sell/hold recommendation.
Link to documentation: https://kinola-iq.github.io/stock-analyst/index.html
- Single-ticker research service via
POST /v1/analyze-stock/ - Root
ResearchCoordinatorLLM agent orchestrates analysis analyse_tickertool fetches yfinance data, extracts financial metrics, scores news sentiment, generates a Python analysis script, and computes a verdictresearch_agentsub-agent is available for web-based research and findings storagecoding_agentsub-agent is a available for performing analytics according to available skills.- In-memory session and result storage
- API-key protected endpoint plus health checks
- FastAPI application with startup/shutdown lifecycle
- API key validation using
X-API-Key - Health endpoints for service & model readiness
- Rotating file logging (
app.logwith backups) - In-memory result storage with basic LRU eviction
- Test coverage for routes, utilities, ticker tools, and storage
- Docker multi-stage image for container runtime
- Python 3.10+
piprequirements.txtAPI_KEYenvironment variable for request authenticationGOOGLE_API_KEYenvironment variable for Google ADK / LiteLLM
- fastapi
- uvicorn
- yfinance
- nest_asyncio
- vaderSentiment
- protobuf==5.29.6
- google-adk
- litellm
- pytest
- pytest-mock
- pytest-asyncio
- pytest-benchmark
- Clone the repository:
git clone <repository-url>
cd stock-analyst- Create and activate a virtual environment:
On macOS/Linux:
python -m venv venv
source venv/bin/activateOn Windows PowerShell:
python -m venv venv
.\venv\Scripts\Activate.ps1- Install dependencies:
pip install -r requirements.txt- Create a
.envfile in the project root:
API_KEY=your-secret-api-key
GOOGLE_API_KEY=your-google-api-key
APP_NAME=stock-analyst
USER_ID=default_user
SESSION_ID=default_session
HOST=0.0.0.0
PORT=8080- Start the application:
python main.pyOr start with Uvicorn directly:
uvicorn main:app --host 0.0.0.0 --port 8080Note: the Docker image exposes port
8501internally, while local development uses thePORTenvironment variable (default8080).
All analysis requests require the X-API-Key header.
curl -X POST http://127.0.0.1:8080/v1/analyze-stock/ \
-H "Content-Type: application/json" \
-H "X-API-Key: your-secret-api-key" \
-d '{"ticker":"AAPL"}'Request body schema:
{
"ticker": "AAPL"
}Example response schema:
{
"result": "<analysis text>",
"findings": "<research findings>",
"status": "success",
"timestamp": "2026-06-25T12:00:00"
}GET /health- basic service healthGET /v1/health_runner- runner initialization statusGET /v1/health_model- model readiness status
stock-analyst/
├── main.py
├── requirements.txt
├── Dockerfile
├── Interface/
│ └── routes.py
├── system/
│ ├── agents/
│ │ ├── finance_agent/
│ │ │ ├── agent.py
│ │ │ ├── tools.py
│ │ │ ├── sub_agents.py
│ │ │ ├── __init__.py
│ │ │ ├── skills/
│ │ │ │ ├── financial_analysis.md
│ │ │ │ ├── standard guide.md
│ │ │ │ └── visualizations.md
│ │ │ └── tools_config/
│ │ │ └── ticker_tools.py
│ └── utility/
│ ├── custom_exceptions.py
│ ├── logger.py
│ ├── model.py
│ ├── result_storage.py
│ ├── schema.py
│ └── utils.py
├── tests/
└── docs/
- The service uses an in-memory session service and result storage.
API_KEYis required for authenticated requests.GOOGLE_API_KEYmust be present at startup or the app fails to initialize.- Ticker input is validated as alphabetic only and limited to 6 characters.
- Agent output is streamed, so analysis may take several seconds.
- Docker defaults to
8501inside the container. docs/PROJECT_ANALYSIS.mdcontains a more detailed design and status assessment.
Run the test suite with:
pytest tests/ -qBuild and run the container:
docker build -t stock-analyst:latest .
docker run -p 8501:8501 --env-file .env stock-analyst:latestThis repository does not currently declare a license. Add one before public distribution or reuse.

