Initial commit: Discord stock price bot with hourly PYPL updates

Implemented Discord bot for automated stock price tracking and reporting with the following features:

- Hourly PayPal (PYPL) stock price updates during NYSE market hours
- Custom branding for PYPL as "Steaks Stablecoin Value"
- Manual stock price queries via !stock and !price commands
- Multi-provider stock API support (Yahoo Finance and Finnhub)
- NYSE market hours detection with holiday awareness
- Discord embed formatting with color-coded price changes
- Docker containerization for consistent deployment
- Comprehensive documentation and deployment guides

Technical stack:
- Python 3.9+ with discord.py
- Finnhub API for stock price data
- APScheduler for hourly automated updates
- Docker support for local and Unraid deployment

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Michael Simard
2025-12-02 21:54:11 -06:00
commit 5964cadf94
14 changed files with 946 additions and 0 deletions

222
README.md Normal file
View File

@@ -0,0 +1,222 @@
# Discord Stock Bot
A Discord bot that automatically posts hourly stock price updates for PayPal (PYPL) during NYSE market hours. The bot also supports manual queries for any stock ticker via prefix commands.
## Features
- **Hourly automated updates**: Posts PayPal stock price every hour during market hours (9:30 AM - 4:00 PM ET, Monday-Friday)
- **Market hours awareness**: Automatically skips updates when NYSE is closed (weekends and holidays)
- **Manual stock queries**: Query any stock ticker using `!stock TICKER` or `!price TICKER`
- **Rich embeds**: Color-coded Discord embeds with price changes and market status
- **API agnostic design**: Abstract stock API layer allows easy switching between data providers
- **Docker containerized**: Consistent deployment across local and production environments
## Commands
- `!stock <TICKER>` or `!price <TICKER>` - Get current stock price for any ticker
- `!market` - Check if NYSE is currently open and view trading hours
- `!ping` - Check bot responsiveness and latency
## Project Structure
```
discord-stock-bot/
├── bot.py # Main bot application
├── config.py # Configuration management
├── market_hours.py # NYSE market hours detection
├── stock_api/
│ ├── __init__.py
│ ├── base.py # Abstract base class for stock APIs
│ └── yahoo.py # Yahoo Finance implementation
├── requirements.txt # Python dependencies
├── Dockerfile # Container definition
├── docker-compose.yml # Docker Compose configuration
└── .env # Environment variables (create from .env.example)
```
## Setup Instructions
### Prerequisites
- Python 3.11+ (for local development)
- Docker and Docker Compose (for containerized deployment)
- Discord Bot Token ([Create one here](https://discord.com/developers/applications))
- Discord Channel ID ([How to get Channel ID](https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID))
### 1. Create Discord Bot
1. Go to [Discord Developer Portal](https://discord.com/developers/applications)
2. Click "New Application" and give it a name
3. Navigate to "Bot" section and click "Add Bot"
4. Under "Privileged Gateway Intents", enable:
- Message Content Intent
5. Copy the bot token (you will need this for `.env` file)
6. Navigate to "OAuth2" > "URL Generator"
7. Select scopes: `bot`
8. Select bot permissions: `Send Messages`, `Embed Links`, `Read Messages/View Channels`
9. Copy the generated URL and use it to invite the bot to your server
### 2. Get Channel ID
1. Enable Developer Mode in Discord (User Settings > Advanced > Developer Mode)
2. Right-click the channel where you want price updates
3. Click "Copy Channel ID"
### 3. Configure Environment
```bash
# Navigate to project directory
cd discord-stock-bot
# Copy example environment file
cp .env.example .env
# Edit .env with your values
# DISCORD_TOKEN=your_actual_bot_token
# CHANNEL_ID=your_actual_channel_id
```
### 4. Run Locally with Docker
```bash
# Build and start the container
docker compose up --build
# Run in detached mode (background)
docker compose up -d
# View logs
docker compose logs -f
# Stop the bot
docker compose down
```
### 5. Run Locally without Docker (Development)
```bash
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Run the bot
python bot.py
```
## Deployment to Unraid
### Method 1: Docker Compose (Recommended)
1. Copy the entire `discord-stock-bot` directory to your Unraid server
2. SSH into your Unraid server
3. Navigate to the project directory
4. Create and configure `.env` file
5. Run: `docker compose up -d`
### Method 2: Unraid Docker Template
1. Open Unraid web interface
2. Navigate to Docker tab
3. Click "Add Container"
4. Configure with these settings:
- **Name**: `discord-stock-bot`
- **Repository**: Build and push your image to Docker Hub first, then use `your-username/discord-stock-bot:latest`
- **Network Type**: `bridge`
- **Add Variables**:
- `DISCORD_TOKEN` = your bot token
- `CHANNEL_ID` = your channel ID
- `PRIMARY_TICKER` = PYPL
- `COMMAND_PREFIX` = !
- `TZ` = America/New_York
### Method 3: Build and Push to Docker Hub
```bash
# Build the image
docker build -t your-username/discord-stock-bot:latest .
# Login to Docker Hub
docker login
# Push to Docker Hub
docker push your-username/discord-stock-bot:latest
# On Unraid, pull and run
docker pull your-username/discord-stock-bot:latest
docker run -d --name discord-stock-bot \
--env-file .env \
--restart unless-stopped \
your-username/discord-stock-bot:latest
```
## Configuration Options
Environment variables in `.env`:
| Variable | Description | Default |
|----------|-------------|---------|
| `DISCORD_TOKEN` | Your Discord bot token | Required |
| `CHANNEL_ID` | Discord channel ID for updates | Required |
| `COMMAND_PREFIX` | Command prefix for bot | `!` |
| `PRIMARY_TICKER` | Stock ticker for hourly updates | `PYPL` |
| `UPDATE_INTERVAL_HOURS` | Hours between updates | `1` |
## Switching Stock API Providers
The bot is designed with an abstract API layer. To switch providers:
1. Create a new class in `stock_api/` that inherits from `StockAPIBase`
2. Implement the required methods: `get_stock_price()` and `is_available()`
3. Update `bot.py` to use your new provider instead of `YahooFinanceAPI`
Example:
```python
# In bot.py
from stock_api import YourNewAPI
# In __init__ method
self.stock_api = YourNewAPI()
```
## Market Hours
The bot respects NYSE trading hours:
- **Trading Days**: Monday - Friday
- **Trading Hours**: 9:30 AM - 4:00 PM Eastern Time
- **Holidays**: Major NYSE holidays are observed (New Year's Day, MLK Day, Presidents Day, Good Friday, Memorial Day, Juneteenth, Independence Day, Labor Day, Thanksgiving, Christmas)
## Troubleshooting
### Bot does not connect
- Verify `DISCORD_TOKEN` is correct
- Ensure bot has been invited to your server
- Check bot has proper permissions in the channel
### Bot does not post updates
- Verify `CHANNEL_ID` is correct
- Ensure bot has permission to send messages in the channel
- Check if market is open using `!market` command
- View logs: `docker compose logs -f`
### Stock data not available
- Yahoo Finance may be experiencing issues
- Ticker symbol may be invalid
- Try using `!stock AAPL` to test with a known ticker
### Container will not start
- Verify `.env` file exists and is properly formatted
- Check Docker logs: `docker compose logs`
- Ensure no other container is using the same name
## License
This project is provided as-is for educational and personal use.
## Acknowledgments
- Stock data provided by Yahoo Finance via `yfinance`
- Built with `discord.py`
- Scheduling powered by `APScheduler`