Compare commits

..

4 Commits

Author SHA1 Message Date
11509ba8c7 fix: merge script now writes to current directory for volume compatibility
Changed merge_jsonl.py to use os.getcwd() instead of os.path.dirname(__file__)
to ensure merged.jsonl is written to the working directory where data files exist,
not to the script's installation directory.

Root cause:
- Dockerfile copies scripts to /app/scripts/ for volume compatibility
- entrypoint.sh runs: cd /app/data && python /app/scripts/merge_jsonl.py
- Old logic used script directory (/app/scripts/), ignoring working directory
- This caused merged.jsonl to be created in /app/scripts/ instead of /app/data/
- Since /app/data/ is volume-mounted, merged file was not visible to host

Solution:
- Scripts now respect current working directory (Unix philosophy)
- Works correctly with volume mounts and script relocation
- Tested in both local and Docker directory structure scenarios

Fixes the issue where merged.jsonl was missing from mounted data volume.
2025-10-31 00:03:39 -04:00
1785f9b06f feat: automate merged.jsonl creation during price fetching
Streamline the data preparation workflow by having get_daily_price.py
automatically invoke merge_jsonl.py after fetching all stock prices.

Changes:
- Modified get_daily_price.py to call merge_jsonl.py automatically
- Updated entrypoint.sh to remove redundant merge_jsonl.py call
- Updated main.sh to remove redundant merge_jsonl.py call
- Fixed import order for linting compliance

Benefits:
- Single command now handles both fetching and merging
- Ensures merged.jsonl is always created after price updates
- Simplifies Docker container startup process
- Prevents missing merged.jsonl errors in production
2025-10-30 23:48:12 -04:00
55206549c7 feat: add configurable volume path for persistent data
Add VOLUME_PATH environment variable to customize storage location for
all persistent data (data/, logs/, configs/ subdirectories).

Changes:
- .env.example: Add VOLUME_PATH variable with documentation
- docker-compose.yml: Use ${VOLUME_PATH:-.} for all volume mounts
- docs/DOCKER.md: Document custom volume location feature

Benefits:
- Store data outside project directory (e.g., on separate disk)
- Easier backup/restore (single directory)
- Clean separation of code and data
- Support for absolute or relative paths

Usage:
  # In .env file
  VOLUME_PATH=/home/user/trading-data

  # Results in mounts:
  /home/user/trading-data/data:/app/data
  /home/user/trading-data/logs:/app/logs
  /home/user/trading-data/configs:/app/configs

Defaults to current directory (.) if not set for backward compatibility.
2025-10-30 23:40:21 -04:00
9e05ce0891 fix: prevent price data overwrite on container restart
Preserve existing merged.jsonl to avoid data loss and API rate limits.
Only fetch new data if merged.jsonl is missing or empty.

Problem:
- Entrypoint always fetched fresh data from Alpha Vantage on every start
- Overwrote existing mounted data directory
- Caused API rate limit issues and data inconsistencies
- Lost historical data needed for backtesting specific date ranges

Solution:
- Check if merged.jsonl exists and has content before fetching
- Display stock count when using existing data
- Provide manual refresh instructions for when updates are needed

Benefits:
- Faster container startup (no API calls if data exists)
- Avoids Alpha Vantage rate limits (5 calls/min, 500/day)
- Preserves user's existing historical datasets
- Enables reliable backtesting with consistent data

To refresh data: rm data/merged.jsonl && docker-compose restart
2025-10-30 23:27:58 -04:00
7 changed files with 73 additions and 19 deletions

View File

@@ -30,3 +30,9 @@ WEB_HTTP_PORT=8888
# Agent Configuration
AGENT_MAX_STEP=30
# Data Volume Configuration
# Base directory for all persistent data (will contain data/, logs/, configs/ subdirectories)
# Use relative paths (./volumes) or absolute paths (/home/user/ai-trader-volumes)
# Defaults to current directory (.) if not set
VOLUME_PATH=.

View File

@@ -1,8 +1,12 @@
import requests
import os
from dotenv import load_dotenv
load_dotenv()
import json
import os
import subprocess
import sys
import requests
from dotenv import load_dotenv
load_dotenv()
all_nasdaq_100_symbols = [
@@ -42,4 +46,15 @@ if __name__ == "__main__":
for symbol in all_nasdaq_100_symbols:
get_daily_price(symbol)
get_daily_price("QQQ")
get_daily_price("QQQ")
# Automatically run merge after fetching
print("\n📦 Merging price data...")
try:
script_dir = os.path.dirname(os.path.abspath(__file__))
merge_script = os.path.join(script_dir, "merge_jsonl.py")
subprocess.run([sys.executable, merge_script], check=True)
print("✅ Price data merged successfully")
except Exception as e:
print(f"⚠️ Failed to merge data: {e}")
print(" Please run 'python merge_jsonl.py' manually")

View File

@@ -18,7 +18,8 @@ all_nasdaq_100_symbols = [
]
# 合并所有以 daily_price 开头的 json逐文件一行写入 merged.jsonl
current_dir = os.path.dirname(__file__)
# Use current working directory instead of script directory for volume compatibility
current_dir = os.getcwd()
pattern = os.path.join(current_dir, 'daily_price*.json')
files = sorted(glob.glob(pattern))

View File

@@ -5,9 +5,9 @@ services:
# build: .
container_name: ai-trader-app
volumes:
- ./data:/app/data
- ./logs:/app/logs
- ./configs:/app/configs
- ${VOLUME_PATH:-.}/data:/app/data
- ${VOLUME_PATH:-.}/logs:/app/logs
- ${VOLUME_PATH:-.}/configs:/app/configs
environment:
# AI Model API Configuration
- OPENAI_API_BASE=${OPENAI_API_BASE}

View File

@@ -112,17 +112,43 @@ docker-compose up
### Volume Mounts
Docker Compose mounts three volumes:
Docker Compose mounts three volumes for persistent data. By default, these are stored in the project directory:
- `./data:/app/data` - Price data and trading records
- `./logs:/app/logs` - MCP service logs
- `./configs:/app/configs` - Configuration files (allows editing configs without rebuilding)
Data persists across container restarts. To reset:
### Custom Volume Location
You can change where data is stored by setting `VOLUME_PATH` in your `.env` file:
```bash
# Store data in a different location
VOLUME_PATH=/home/user/trading-data
# Or use a relative path
VOLUME_PATH=./volumes
```
This will store data in:
- `/home/user/trading-data/data/`
- `/home/user/trading-data/logs/`
- `/home/user/trading-data/configs/`
**Note:** The directory structure is automatically created. You'll need to copy your existing configs:
```bash
# After changing VOLUME_PATH
mkdir -p /home/user/trading-data/configs
cp configs/custom_config.json /home/user/trading-data/configs/
```
### Reset Data
To reset all trading data:
```bash
docker-compose down
rm -rf data/agent_data/* logs/*
rm -rf ${VOLUME_PATH:-.}/data/agent_data/* ${VOLUME_PATH:-.}/logs/*
docker-compose up
```

View File

@@ -38,12 +38,18 @@ fi
echo "✅ Environment variables validated"
# Step 1: Data preparation
echo "📊 Fetching and merging price data..."
# Run scripts from /app/scripts but output to /app/data
cd /app/data
python /app/scripts/get_daily_price.py
python /app/scripts/merge_jsonl.py
cd /app
echo "📊 Checking price data..."
if [ -f "/app/data/merged.jsonl" ] && [ -s "/app/data/merged.jsonl" ]; then
echo "✅ Using existing price data ($(wc -l < /app/data/merged.jsonl) stocks)"
echo " To refresh data, delete /app/data/merged.jsonl and restart"
else
echo "📊 Fetching and merging price data..."
# Run script from /app/scripts but output to /app/data
# Note: get_daily_price.py now automatically calls merge_jsonl.py after fetching
cd /app/data
python /app/scripts/get_daily_price.py
cd /app
fi
# Step 2: Start MCP services in background
echo "🔧 Starting MCP services..."

View File

@@ -10,8 +10,8 @@ echo "🚀 Launching AI Trader Environment..."
echo "📊 Now getting and merging price data..."
cd ./data
# Note: get_daily_price.py now automatically calls merge_jsonl.py after fetching
python get_daily_price.py
python merge_jsonl.py
cd ../
echo "🔧 Now starting MCP services..."