- Add rl_agent/ project with RecurrentPPO trading agent - 24 discrete actions (market/limit orders, stop-loss, trailing stop) - Position-based P&L rewards with alpha vs SPY tracking - Discord alerts and watchlist sync integration - Alpaca paper trading execution - Add src/alerting module for day trader alerts - Add tests for market data, prompt construction, ticker detection - Add on_message_edit handler for edited Discord mentions - Rename rl_agent READMEs to descriptive names (SRC_README.md, etc.) - Update .gitignore to exclude RL agent models, logs, tensorboard - Improve training scripts with multi-GPU and monitoring |
||
|---|---|---|
| .claude | ||
| config | ||
| docker | ||
| llama-swap | ||
| llama.cpp@bd2a93d475 | ||
| recommendation_analysis | ||
| rl_agent | ||
| src | ||
| tests | ||
| training | ||
| .env.template | ||
| .gitignore | ||
| docker-compose.yml | ||
| README.md | ||
| README_RL_Algorithm | ||
| requirements.txt | ||
| save_point.md | ||
| start.sh | ||
Finance Bro Bot
A sophisticated Discord bot powered by a fine-tuned Qwen2.5-14B language model, specializing in financial analysis, stock recommendations, and market insights. The bot combines real-time market data from Yahoo Finance and SEC EDGAR filings with a custom-trained LLM to provide comprehensive stock analysis with a distinctive "finance bro" personality.
Project Overview
Finance Bro Bot is a complete end-to-end solution that includes:
- Discord Bot Interface: Responds to mentions and DMs with financial analysis
- Fine-tuned LLM: Qwen2.5-14B model (
finance-bro-v2-q4_k_m) trained on 39 financial documents using QLoRA - Real-time Data Integration: Yahoo Finance quotes, news, and SEC EDGAR filings
- Technical Analysis: RSI, MACD, Bollinger Bands, SMA/EMA, and more
- Document RAG: PDF document search for reference materials
- Containerized Deployment: Docker Compose setup with llama.cpp server
Key Features
| Feature | Description |
|---|---|
| Stock Quotes | Real-time prices via Yahoo Finance with fallback APIs |
| Extended Hours Prices | Pre-market and after-hours quotes via Yahoo Finance |
| Technical Indicators | RSI, MACD, SMA, EMA, Bollinger Bands, Stochastic |
| News Sentiment | Fetches and analyzes recent news with sentiment scoring |
| SEC Filings | Pulls financial statements from SEC EDGAR XBRL API |
| Recommendations | Buy/Hold/Sell recommendations with timeframe options |
| Watchlist System | Per-user watchlists with price tracking and alerts |
| Hourly Summaries | Automated price updates at the top of each hour |
| Conversation Memory | Per-user conversation history for context |
| PDF Knowledge Base | Reference document search and retrieval |
Table of Contents
Quick Start
Prerequisites
- Docker and Docker Compose
- NVIDIA GPU with 16GB+ VRAM (for llama.cpp inference)
- Discord Bot Token (create one here)
Installation
# Clone the repository
git clone <repo-url>
cd finance-bro-bot
# Copy environment template
cp .env.template .env
# Edit .env and add your Discord bot token
nano .env
# Start the services
docker compose up -d
# Check logs
docker compose logs -f discord-bot
Project Structure
finance-bro-bot/
├── config/ # Configuration files
│ ├── settings.py # Application settings (env vars)
│ ├── init_prompt.txt # Bot personality configuration
│ └── ignored_words.txt # Words to ignore in ticker detection
├── src/ # Source code
│ ├── bot/ # Discord bot implementation
│ │ ├── discord_client.py # Main bot client
│ │ └── commands.py # Slash commands
│ ├── data/ # Data persistence
│ │ └── watchlist_db.py # SQLite watchlist database
│ ├── finance/ # Financial data services
│ │ └── stock_data.py # Alpaca, Yahoo Finance, SEC EDGAR integration
│ ├── alerting/ # Day trader alert system
│ │ └── __init__.py # Price history, SMA alerts
│ ├── llm/ # LLM client
│ │ └── client.py # OpenAI-compatible API client
│ └── documents/ # Document processing
│ └── pdf_loader.py # PDF loading and search
├── rl_agent/ # RL Trading Agent (separate project)
│ ├── src/ # Agent source code
│ ├── config/ # Agent configuration
│ ├── models/ # Trained model checkpoints (not in git)
│ ├── logs/ # Training logs (not in git)
│ ├── tensorboard/ # TensorBoard logs (not in git)
│ ├── tests/ # Agent tests
│ └── README_RL_AGENT.md # RL Agent documentation
├── db/ # Database files
│ ├── watchlist.db # SQLite database
│ └── WATCHLIST_README.md # Watchlist documentation
├── training/ # Model fine-tuning pipeline (for LLM)
│ ├── prepare_data.py # Convert PDFs to training data
│ ├── finetune.py # Single-GPU fine-tuning script
│ ├── finetune_multigpu.py # Multi-GPU fine-tuning with early stopping
│ ├── merge_lora.py # Merge LoRA weights with base model
│ ├── convert_hf_to_gguf.py # Convert to GGUF format
│ └── data/ # Training data (generated)
├── models/ # GGUF model files
├── data/ # PDF reference documents
├── logs/ # Application logs
├── docker-compose.yml # Container orchestration
├── requirements.txt # Python dependencies
├── .env # Environment variables (not in git)
└── .env.template # Environment variable template
Root Directory Files
docker-compose.yml
Orchestrates the two-container setup:
- llama-server: llama.cpp server running the fine-tuned GGUF model with CUDA acceleration
- discord-bot: Python Discord bot that connects to the LLM server
requirements.txt
Python dependencies for the Discord bot:
discord.py- Discord API wrapperaiohttp- Async HTTP client for LLM APIyfinance- Yahoo Finance datapymupdf- PDF text extraction
.env.template
Template for required environment variables:
DISCORD_BOT_TOKEN=your_token_here
LLM_API_BASE=http://llama-server:8000
LLM_MODEL_NAME=finance-bro-v2-q4_k_m
Configuration
See config/CONFIG_README.md for detailed configuration documentation.
Key configuration files:
config/settings.py- Environment-based settings (tokens, API URLs, model params)config/init_prompt.txt- Bot personality and behavior instructionsconfig/ignored_words.txt- Words to exclude from ticker detection
Running the Bot
With Docker (Recommended)
# Start all services
docker compose up -d
# View logs
docker compose logs -f discord-bot
# Restart after code changes
docker compose restart discord-bot
# Stop everything
docker compose down
Locally (Development)
# Install dependencies
pip install -r requirements.txt
# Run the bot (requires llama-server running separately)
python -m src.bot.discord_client
Training Pipeline
See training/TRAINING_README.md for detailed training documentation.
Overview
The training pipeline fine-tunes Qwen2.5-14B on financial documents using QLoRA:
- Data Preparation:
prepare_data.pyconverts PDFs to chat-format training data - Fine-tuning:
finetune_multigpu.pytrains LoRA adapters with early stopping - Merging:
merge_lora.pycombines LoRA weights with the base model - Conversion:
convert_hf_to_gguf.pycreates GGUF files for llama.cpp
Quick Training
# Prepare training data from PDFs
python training/prepare_data.py
# Fine-tune (on GPU)
CUDA_VISIBLE_DEVICES=1 python training/finetune_multigpu.py
# Merge LoRA and convert to GGUF
python training/merge_lora.py
python training/convert_hf_to_gguf.py --outfile models/new-model.gguf
Documentation
| Document | Description |
|---|---|
| config/CONFIG_README.md | Configuration files and settings |
| src/SRC_README.md | Source code architecture and modules |
| db/WATCHLIST_README.md | Watchlist system, price tracking, and news sentiment |
| training/TRAINING_README.md | Fine-tuning pipeline and scripts |
| rl_agent/README_RL_AGENT.md | RL Trading Agent documentation |
RL Trading Agent
The RL Trading Agent is a separate project within this repository that uses reinforcement learning to make autonomous trading decisions on Alpaca paper trading.
Overview
- Algorithm: Recurrent PPO (LSTM-based policy for sequential decision making)
- State Space: 32 static features + 60-step OHLCV sequences
- Action Space: 24 discrete actions (HOLD, market/limit orders at various position sizes, stop-loss, trailing stop)
- Reward: Position-based P&L with alpha vs SPY benchmark
Key Features
| Feature | Description |
|---|---|
| Live Paper Trading | Executes real orders on Alpaca paper account |
| Alpha Tracking | Rewards beating SPY at portfolio and position level |
| Risk Management | 50% cash reserve, PDT checks, tradeable status |
| Discord Alerts | Sends trade notifications to Discord webhook |
| Watchlist Sync | Syncs positions to Finance Bro Bot's /positions command |
| PostgreSQL Logging | Logs trades, daily metrics, and episodes |
Quick Start
# Start the RL agent container
docker compose up -d rl-agent
# View training logs
docker compose logs -f rl-agent
# Monitor with TensorBoard
tensorboard --logdir rl_agent/tensorboard
Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Market Data │────▶│ RL Agent │────▶│ Alpaca API │
│ (yfinance) │ │ (RecurrentPPO) │ │ (Paper Trading)│
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Discord/DB │
│ - Trade alerts │
│ - Watchlist │
│ - PostgreSQL │
└─────────────────┘
See rl_agent/README_RL_AGENT.md for full documentation.
Bot Commands
Slash Commands
| Command | Description |
|---|---|
/quote SYMBOL |
Get real-time stock quote |
/news SYMBOL |
Get recent news for a stock |
/watch SYMBOL |
Add a stock to your personal watchlist |
/unwatch SYMBOL |
Remove a stock from your watchlist |
/watchlist |
View your current watchlist with prices |
/ask QUESTION |
Ask the bot a question |
/docs |
List loaded reference documents |
/status |
Check bot and LLM server status |
/reset |
Clear your conversation history |
/help |
Show available commands |
Text Commands (via @mention)
You can also use these commands by mentioning the bot:
@Finance Bro Bot /watch AAPL, TSLA- Add multiple stocks to watchlist@Finance Bro Bot /unwatch AAPL- Remove from watchlist
Mentions
Mention the bot in the #stockstuff channel (configurable) to interact:
@Finance Bro Bot what's your recommendation on AAPL?
The bot will ask for your timeframe (short/medium/long-term) before providing analysis.
Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Discord API │────▶│ Discord Bot │────▶│ llama.cpp │
│ │◀────│ (Python) │◀────│ Server (CUDA) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ External APIs │
│ - Yahoo Finance│
│ - Alpaca │
│ - Finnhub │
│ - SEC EDGAR │
└─────────────────┘
▲
│
┌─────────────────┐ ┌─────────────────┐
│ Market Data │────▶│ RL Trading │────▶ Alpaca Paper Trading
│ (yfinance) │ │ Agent (PPO) │────▶ Discord Alerts
└─────────────────┘ └─────────────────┘────▶ PostgreSQL Logging
Data Sources
| Data Type | Source | Notes |
|---|---|---|
| Regular hours prices | Alpaca (batch) | Fast, reliable, 100 symbols/call |
| Extended hours prices | Yahoo Finance | Pre-market and after-hours via yfinance 1.0 |
| News headlines | Yahoo Finance RSS | Falls back to API if RSS fails |
| Fundamentals | Finnhub + SEC EDGAR | P/E, EPS, revenue, etc. |
| Insider transactions | Finnhub | Recent buys/sells |
Background Tasks
The bot runs several automated tasks:
| Task | Schedule | Description |
|---|---|---|
hourly_watchlist_summary |
Top of each hour (5 AM - 7 PM ET) | Posts price summary for all watchlisted stocks |
market_open_summary |
9:30 AM ET daily | Posts opening prices for watchlist stocks |
watchlist_price_updater |
Every 10 min | Updates cached prices for watchlist and alert calculations |
news_sentiment_updater |
15 min (market) / 2 hr (off) | Fetches news and scores sentiment |
health_monitor |
Every 15 min | Checks LLM server health |
account_position_sync |
Every hour | Syncs Alpaca account positions |
watchlist_expiry_checker |
9 AM ET daily | Checks for expiring watchlist items |
Regression Testing & Quality Checklist
When making changes to the bot, verify the following functionality:
Critical Output Format Tests
Test a recommendation request (e.g., @Finance Bro Bot short term recommendation on AAPL) and verify:
| Check | Expected | File Location |
|---|---|---|
| Price displayed correctly | **TICKER - $XX.XX** (+/-X.XX% today) with exact price from Yahoo Finance |
discord_client.py:834-848 |
| Technical Analysis section | RSI, SMA 20/50, MACD, Volume all present with values | discord_client.py:850-886 |
| News Sentiment with scores | Each headline shows - "headline" (source) - **+/-X.X** (Label) |
discord_client.py:889-955 |
| Overall Sentiment score | **Overall Sentiment: +/-X.XX (Label)** at end of news section |
discord_client.py:942-953 |
| Recommendation line | **Recommendation:** [action] - [reason] |
discord_client.py:401 |
| Key Risks line | **Key Risks:** [brief risk] |
discord_client.py:402 |
| No hallucinated prices | Price matches actual Yahoo Finance data, not made up | Verify against /quote TICKER |
Known Issues to Watch For
-
Model ignores format instructions: The V3 fine-tuned model may ignore system prompts. The hybrid approach in
_build_recommendation_response()pre-formats data to work around this. -
Chinese characters in output: The model sometimes outputs Chinese text. Filtered via
re.sub(r'[\u4e00-\u9fff]+', '', response)indiscord_client.py:392. -
Price hallucination: If the model makes up prices instead of using provided data, check that
market_data_contextis being passed correctly in the system prompt. -
Repetition loops: If the model repeats itself, verify
repeat_penalty,frequency_penalty, andpresence_penaltyinllm/client.py:73-76. -
News dates from distant past: News is now filtered to prioritize articles from the last 7 days, falling back to 7-30 day old articles only if needed. Articles older than 30 days are excluded. See
_filter_news_by_recency()instock_data.py.
Sentiment Scoring
The keyword-based sentiment scoring uses these word lists in discord_client.py:915-916:
- Positive: up, gain, surge, jump, rise, soar, best, top, winner, bull, growth, profit, beat, outperform, rally
- Negative: down, drop, fall, crash, plunge, sink, worst, loss, bear, decline, miss, fail, sell, cut, warning, concern
Score calculation:
- More positive words → score +0.3 to +0.8
- More negative words → score -0.3 to -0.8
- Equal or no keywords → score 0.0 (Neutral)
Testing Commands
# Test inside container
docker exec finance-bro-bot python3 -c "
import asyncio
from src.finance.stock_data import StockDataService
async def test():
quote = await StockDataService.get_quote('AAPL')
print(f'Price: {quote.get(\"price\")}')
indicators = await StockDataService.get_technical_indicators('AAPL')
print(f'RSI: {indicators.get(\"rsi_14\")}')
asyncio.run(test())
"
# Check bot logs
docker compose logs --tail=50 discord-bot
# Restart after changes
docker compose restart discord-bot
Model Configuration
Current model: finance-bro-v3-q4_k_m (configured in docker-compose.yml:78)
LLM parameters in llm/client.py:
temperature: 0.3 (from settings)repeat_penalty: 1.5frequency_penalty: 0.7presence_penalty: 0.5stop: ["---", "signing off", "See ya", "Remember:", "Note:"]
License
This project is for educational purposes. Not financial advice.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
For questions or issues, open a GitHub issue.