Files
kaedwen ea141eb012
Build and Push Docker Image / build-and-push (push) Failing after 1m41s
initial
2026-07-02 20:09:44 +02:00

458 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI Trading Application
AI-assisted trading application with Interactive Brokers integration, news aggregation, and configurable trading strategies.
## Features
**Phase 1: Foundation**
- Go module structure
- SQLite database with migrations
- Configuration via environment variables
- Structured JSON logging
- Graceful shutdown handling
**Phase 2: IB Gateway Integration**
- Interactive Brokers API client
- Connection with retry logic and exponential backoff
- Account balance tracking (every 5 minutes)
- Order placement and cancellation
- Market data subscription support
**Phase 3: News Aggregation**
- RSS feed integration (CNBC, MarketWatch, Reuters)
- Keyword-based sentiment analysis
- Article deduplication by URL
- Symbol extraction from news content
- Automatic news polling (configurable interval)
**Phase 4: Trading Strategies**
- Three configurable strategies: defensive, normal, aggressive
- Risk parameters per strategy (max trades, position size, stop-loss)
- Sentiment-based trade signal generation
- Comprehensive test coverage
**Phase 5: Trade Execution Engine**
- Pending trade workflow with configurable timeout
- Rate limiting (hourly and parallel trade limits)
- Trade repository with full lifecycle tracking
- Stop-loss order management
- Trade executor with order placement
- User approval/rejection of pending trades
- Force immediate execution option
**Phase 6: Web Dashboard**
- HTML/JavaScript frontend with real-time updates
- Server-Sent Events (SSE) for live trade notifications
- OpenID Connect authentication via Authelia (optional)
- Trade management UI (approve/reject/force)
- **Whitelist Management UI** - Add/edit/disable trading symbols with WKN/ISIN
- Real-time balance and statistics display
- Tabbed interface (Overview/Trades/Whitelist)
- Responsive design with modal forms
- Health check endpoint
**Phase 8: LLM-Based Sentiment Analysis** (Optional)
- Ollama integration for contextual sentiment analysis
- Ensemble mode: weighted average of LLM + keyword scoring
- Graceful fallback to keyword analyzer on LLM timeout
- Support for Mistral, Llama2, and other Ollama models
- Configurable temperature and timeout
- Enhanced accuracy for complex financial language
## Status
**Completed:** Phases 1-6, 8 ✅
**Production Ready:** Backend complete with optional LLM sentiment enhancement
## Optional: LLM-Based Sentiment Analysis
The application can optionally use a local LLM (via **Ollama**) for more accurate sentiment analysis:
**Benefits:**
- Context-aware: understands "beats expectations despite loss" as positive
- Handles negations, sarcasm, and hedging language
- Adaptive to new financial terminology
- Provides confidence scores for position sizing
**Setup:**
```bash
# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
# Pull model (4GB)
ollama pull mistral
# Start Ollama server
ollama serve # Runs on http://localhost:11434
```
**Enable in config:**
```yaml
llm_scorer:
enabled: true
endpoint: http://localhost:11434
model_name: mistral
timeout: 30
temperature: 0.3
ensemble_weight: 0.7 # 70% LLM + 30% keyword
```
**Resource Requirements:**
- CPU-only: 2-4s per article (async processing)
- GPU (NVIDIA 4GB+): 0.5-1s per article
- Memory: 4-8GB RAM
**Fallback:** If LLM times out or Ollama is unavailable, automatically falls back to keyword-based sentiment analysis.
## Docker Deployment
### Quick Start with Docker Compose
```bash
# Prepare data directory for distroless nonroot user
mkdir -p data && chown 65532:65532 data
# Build and run
docker-compose up -d
# View logs
docker-compose logs -f aitrade
# Stop
docker-compose down
```
### Image Details
**Base Image:** Google Distroless (`gcr.io/distroless/static-debian12:nonroot`)
- **Size:** ~23 MB (with healthcheck binary)
- **No CGO:** Pure Go with `modernc.org/sqlite`
- **Embedded Migrations:** No external files needed
- **Health Check:** Built-in lightweight binary (no curl/wget)
- **Security:** Non-root user (UID 65532), minimal attack surface
- **Includes:** CA certificates, timezone data
### Using Pre-built Image from Gitea Registry
```bash
# Pull from registry
docker pull gitea.yourdomain.com/yourusername/aitrade:latest
# Run with environment variables
docker run -d \
-p 8080:8080 \
-v $(pwd)/data:/app/data \
-e TRADING_STRATEGY=normal \
-e DRY_RUN=true \
-e LLM_SCORER_ENABLED=false \
--name aitrade \
gitea.yourdomain.com/yourusername/aitrade:latest
```
### Docker with Ollama (LLM Sentiment)
```bash
# Start both services
docker-compose --profile llm up -d
# Pull Mistral model
docker exec ollama ollama pull mistral
# Enable LLM in aitrade
docker-compose exec aitrade sh -c 'export LLM_SCORER_ENABLED=true'
docker-compose restart aitrade
```
### Build Locally
```bash
# Build image
docker build -t aitrade:local .
# Run
docker run -d -p 8080:8080 -v $(pwd)/data:/app/data aitrade:local
```
### CI/CD Pipeline
The repository includes a Gitea Actions workflow (`.gitea/workflows/docker.yaml`) that automatically:
- Builds Docker image on push to main/master/develop
- Tags images with branch name, commit SHA, and semantic version
- Pushes to Gitea Container Registry
- Creates `latest` tag for default branch
**Triggered by:**
- Push to main/master/develop branches
- Git tags matching `v*` (e.g., `v1.0.0`)
- Pull requests (build only, no push)
**Required Secret:** `GITEA_TOKEN` with registry write permissions
## Quick Start
### Option 1: Native Binary
```bash
# Build
go build -o aitrade ./cmd/aitrade
# Run
./aitrade
```
### Option 2: Docker (Recommended)
```bash
# Using Docker Compose
docker-compose up -d
# Or pull from registry
docker pull gitea.yourdomain.com/username/aitrade:latest
docker run -d -p 8080:8080 -v $(pwd)/data:/app/data gitea.yourdomain.com/username/aitrade:latest
```
### Access
Open browser: `http://localhost:8080`
**Note:** IB Gateway must be running for broker integration. See full documentation in `docs/DOCKER.md`.
## Configuration
The application supports **two configuration methods**:
### Option 1: YAML Configuration (Recommended)
Create a `config.yaml` file in one of these locations:
- `./config.yaml` (current directory)
- `~/.config/aitrade/config.yaml`
- `/etc/aitrade/config.yaml`
- Custom path via `CONFIG_FILE=/path/to/config.yaml`
**Example config.yaml:**
```yaml
trading:
strategy: normal
dry_run: true
dry_run_balance: 100000.0
max_trade_value: 2000.0
watch_symbols:
- AAPL
- MSFT
- GOOGL
database:
path: ./data/aitrade.db
web:
port: "8080"
```
See `config.example.yaml` for a complete configuration file.
### Option 2: Environment Variables
If no YAML file is found, the application uses environment variables:
```bash
# Interactive Brokers
IB_GATEWAY_HOST=127.0.0.1
IB_GATEWAY_PORT=4001
IB_CLIENT_ID=1
# Trading Strategy
TRADING_STRATEGY=normal # defensive, normal, aggressive
STOP_LOSS_ENABLED=true
STOP_LOSS_PERCENT=3.0
# Auto-Trading
TRADING_ENABLED=true # Enable automatic trade generation
TRADING_INTERVAL_SECONDS=60 # How often to analyze market (60s default)
WATCH_SYMBOLS=AAPL,MSFT,GOOGL,TSLA,AMZN # Symbols to monitor
# SELL Triggers
TAKE_PROFIT_PERCENT=5.0 # Sell when profit reaches 5%
HOLD_TIME_MINUTES=30 # Minimum hold time before selling
SELL_ON_NEGATIVE_SENTIMENT=true # Sell on negative news sentiment
# Rate Limiting
MAX_TRADES_PER_HOUR=6
MAX_PARALLEL_TRADES=5
PENDING_TIME_SECONDS=300 # 5 minutes
# Trade Limits
MAX_TRADE_VALUE=2000.0 # Absolute max $ per trade (0 = unlimited)
# Dry Run Mode
DRY_RUN=true # Enable paper trading (no real money)
DRY_RUN_BALANCE=100000.0 # Starting virtual balance
# Database
DB_PATH=./data/aitrade.db
# Web
WEB_PORT=8080
# News
NEWS_POLL_INTERVAL=300 # seconds
# LLM Sentiment Scorer (Optional - requires Ollama)
LLM_SCORER_ENABLED=false # Set to true to enable
LLM_SCORER_ENDPOINT=http://localhost:11434
LLM_SCORER_MODEL=mistral
LLM_SCORER_TIMEOUT_SECONDS=30
LLM_SCORER_TEMPERATURE=0.3
LLM_SCORER_ENSEMBLE_WEIGHT=0.7 # 0.0-1.0 (1.0 = LLM only, 0.7 = 70% LLM + 30% keyword)
# OpenID Connect (Authelia) - Optional
OIDC_ENABLED=false # Set to true to enable
OIDC_ISSUER=https://auth.example.com
OIDC_CLIENT_ID=aitrade
OIDC_CLIENT_SECRET=<secret>
OIDC_REDIRECT_URL=http://localhost:8080/callback
OIDC_SCOPES=openid,profile,email
```
## API Endpoints
### Public
- `GET /health` - Health check
- `GET /callback` - OIDC callback (when auth enabled)
### Protected (requires auth if OIDC enabled)
- `GET /` - Main dashboard
- `GET /trades` - Get all trades (JSON)
- `GET /events` - SSE stream for real-time updates
- `GET /api/balance` - Get current balance
- `GET /api/news` - Get recent news
- `POST /api/trades/{id}/approve?force=bool` - Approve trade
- `POST /api/trades/{id}/reject` - Reject trade (JSON body: `{"reason": "..."}`)
## Web Dashboard Features
- 📊 **Three Tabs:** Overview / All Trades / Whitelist Management
- 💹 Real-time statistics (balance, active trades, pending trades)
- 📈 Complete trade history with reasoning and P&L
- ⏱️ Live countdown timers for pending trades
- ✅ One-click approve/reject/force actions
- 🛡️ **Whitelist Management:** Add/edit/disable symbols with WKN/ISIN identifiers
- ⚡ Only whitelisted & enabled symbols can execute trades
- 🔄 Server-Sent Events for instant updates
- 🔒 Optional OpenID Connect authentication via Authelia
- 📱 Responsive design with modal forms
## Trading Logic
### Position Sizing (Capital Allocation)
The system uses **intelligent position sizing** that considers:
1. **Strategy Base Percentage**
- Defensive: 1.5% of capital per trade
- Normal: 4.0% of capital per trade
- Aggressive: 7.5% of capital per trade
2. **Confidence-Based Scaling**
- High confidence (0.9) → Larger position
- Low confidence (0.5) → Smaller position
- Multiplier ranges:
- Defensive: 0.3x - 0.8x
- Normal: 0.5x - 1.0x
- Aggressive: 0.7x - 1.2x
3. **Parallel Trade Allocation**
- Capital is divided by `MAX_PARALLEL_TRADES`
- Each trade slot gets: `TotalCapital / MaxParallel`
- Example: $100k with 5 parallel → $20k per slot
- Prevents first trade from consuming all capital
4. **Absolute Maximum per Trade**
- `MAX_TRADE_VALUE` sets hard limit (default: 0 = unlimited)
- If calculated trade exceeds limit → quantity reduced to fit
- If price too high for even 1 share → trade rejected
- Example: MAX_TRADE_VALUE=$2000, price $3000 → rejected
**Formula:**
```
capitalPerSlot = totalCapital / maxParallelTrades
adjustedPercent = basePercent * (0.5 + confidence * 0.5)
positionValue = capitalPerSlot * (adjustedPercent / 100)
quantity = floor(positionValue / currentPrice)
```
**Example (Normal Strategy):**
- Total: $100,000
- Max Parallel: 5
- Per Slot: $20,000
- Confidence: 0.72
- Base: 4.0%
- Multiplier: 0.86x
- Adjusted: 3.44%
- Position: $20,000 × 3.44% = $688
- Price: $180
- **Quantity: 3 shares**
### SELL Triggers
Positions are automatically sold when:
1. **Take Profit**: Profit ≥ `TAKE_PROFIT_PERCENT` (default: 5%)
2. **Negative Sentiment**: Strong negative news (if `SELL_ON_NEGATIVE_SENTIMENT=true`)
3. **Stop Loss**: Loss ≥ `STOP_LOSS_PERCENT` (default: 3%)
All SELL trades require minimum hold time (`HOLD_TIME_MINUTES`) before execution.
```bash
go build -o aitrade ./cmd/aitrade
```
## Running
```bash
./aitrade
```
**Note:** IB Gateway or TWS must be running and configured to accept API connections on the specified port.
## Testing
```bash
go test ./...
```
## Architecture
```
/projects/Private/aitrade/
├── cmd/aitrade/ # Application entry point
├── pkg/
│ ├── app/
│ │ ├── client/ # IB Gateway client
│ │ ├── news/ # News aggregation
│ │ ├── strategy/ # Trading strategies
│ │ └── app.go # Main orchestrator
│ ├── config/ # Configuration
│ ├── db/ # Database layer
│ └── model/ # Data models
└── migrations/ # SQL migrations
```
## Strategy Comparison
| Strategy | Max Parallel | Max/Hour | Position Size | Stop-Loss | Sentiment Threshold |
|-------------|--------------|----------|---------------|-----------|---------------------|
| Defensive | 2 | 3 | 1.5% | 2% | >0.5 (3+ pos news) |
| Normal | 5 | 6 | 4.0% | 3% | >0.3 (2+ pos news) |
| Aggressive | 10 | 12 | 7.5% | 5% | >0.0 (1+ pos news) |
## Database Schema
- `trades` - Trade lifecycle tracking (pending → submitted → filled → completed)
- `balances` - Account balance snapshots
- `news_articles` - Aggregated news with sentiment scores
- `schema_migrations` - Migration version tracking
## License
Private project