From 09c147f23639110d61831dc8790d14c074151187 Mon Sep 17 00:00:00 2001 From: DANG RAN Date: Wed, 9 Jul 2025 20:13:29 +0800 Subject: [PATCH] auto trigger daily --- .github/workflows/manual-analysis.yml | 62 ++++++++++ .github/workflows/trading-analysis.yml | 133 +++++++++++++++++++++ GITHUB_ACTIONS.md | 141 +++++++++++++++++++++++ README.md | 27 ++++- cli/non_interactive.py | 107 +++++++++++++++++ results/TSLA/2025-07-09/message_tool.log | 1 + 6 files changed, 470 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/manual-analysis.yml create mode 100644 .github/workflows/trading-analysis.yml create mode 100644 GITHUB_ACTIONS.md create mode 100644 cli/non_interactive.py diff --git a/.github/workflows/manual-analysis.yml b/.github/workflows/manual-analysis.yml new file mode 100644 index 00000000..2fca5116 --- /dev/null +++ b/.github/workflows/manual-analysis.yml @@ -0,0 +1,62 @@ +name: Manual TradingAgents Analysis + +on: + workflow_dispatch: + inputs: + ticker: + description: 'Stock ticker symbol to analyze' + required: true + default: 'NVDA' + type: string + date: + description: 'Analysis date (YYYY-MM-DD format, leave empty for today)' + required: false + default: '' + type: string + +jobs: + analyze: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Set analysis date + id: set_date + run: | + if [ "${{ github.event.inputs.date }}" != "" ]; then + echo "date=${{ github.event.inputs.date }}" >> $GITHUB_OUTPUT + else + echo "date=$(date +%Y-%m-%d)" >> $GITHUB_OUTPUT + fi + + - name: Create output directory + run: mkdir -p results/github-actions + + - name: Run TradingAgents Analysis + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + FINNHUB_API_KEY: ${{ secrets.FINNHUB_API_KEY }} + TRADINGAGENTS_TICKER: ${{ github.event.inputs.ticker }} + TRADINGAGENTS_DATE: ${{ steps.set_date.outputs.date }} + TRADINGAGENTS_OUTPUT_PATH: results/github-actions/analysis-${{ github.run_number }}.md + run: | + python cli/non_interactive.py + + - name: Upload analysis results + uses: actions/upload-artifact@v3 + with: + name: trading-analysis-${{ github.event.inputs.ticker }}-${{ steps.set_date.outputs.date }} + path: results/github-actions/ + retention-days: 30 \ No newline at end of file diff --git a/.github/workflows/trading-analysis.yml b/.github/workflows/trading-analysis.yml new file mode 100644 index 00000000..bf177e4e --- /dev/null +++ b/.github/workflows/trading-analysis.yml @@ -0,0 +1,133 @@ +name: TradingAgents Analysis + +on: + workflow_dispatch: + inputs: + ticker: + description: 'Stock ticker symbol to analyze' + required: true + default: 'NVDA' + type: string + date: + description: 'Analysis date (YYYY-MM-DD format)' + required: false + default: '' + type: string + deep_think_llm: + description: 'Deep thinking LLM model' + required: false + default: 'o4-mini' + type: string + quick_think_llm: + description: 'Quick thinking LLM model' + required: false + default: 'gpt-4o-mini' + type: string + max_debate_rounds: + description: 'Maximum debate rounds' + required: false + default: '1' + type: string + online_tools: + description: 'Use online tools (true/false)' + required: false + default: 'true' + type: string + debug: + description: 'Enable debug mode (true/false)' + required: false + default: 'false' + type: string + schedule: + # Run daily at 9 AM UTC (market open time) + - cron: '0 9 * * 1-5' + push: + branches: [ main ] + paths: + - 'tradingagents/**' + - 'cli/**' + - 'requirements.txt' + - '.github/workflows/trading-analysis.yml' + +jobs: + analyze: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Cache pip dependencies + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Set analysis date + id: set_date + run: | + if [ "${{ github.event.inputs.date }}" != "" ]; then + echo "date=${{ github.event.inputs.date }}" >> $GITHUB_OUTPUT + else + echo "date=$(date +%Y-%m-%d)" >> $GITHUB_OUTPUT + fi + + - name: Create output directory + run: mkdir -p results/github-actions + + - name: Run TradingAgents Analysis + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + FINNHUB_API_KEY: ${{ secrets.FINNHUB_API_KEY }} + TRADINGAGENTS_TICKER: ${{ github.event.inputs.ticker || 'NVDA' }} + TRADINGAGENTS_DATE: ${{ steps.set_date.outputs.date }} + TRADINGAGENTS_DEEP_THINK_LLM: ${{ github.event.inputs.deep_think_llm || 'o4-mini' }} + TRADINGAGENTS_QUICK_THINK_LLM: ${{ github.event.inputs.quick_think_llm || 'gpt-4o-mini' }} + TRADINGAGENTS_MAX_DEBATE_ROUNDS: ${{ github.event.inputs.max_debate_rounds || '1' }} + TRADINGAGENTS_ONLINE_TOOLS: ${{ github.event.inputs.online_tools || 'true' }} + TRADINGAGENTS_DEBUG: ${{ github.event.inputs.debug || 'false' }} + TRADINGAGENTS_OUTPUT_PATH: results/github-actions/analysis-${{ github.run_number }}.md + run: | + python cli/non_interactive.py + + - name: Upload analysis results + uses: actions/upload-artifact@v3 + with: + name: trading-analysis-results-${{ github.run_number }} + path: results/github-actions/ + retention-days: 30 + + - name: Comment on PR (if triggered by PR) + if: github.event_name == 'pull_request' + uses: actions/github-script@v6 + with: + script: | + const fs = require('fs'); + const path = require('path'); + + try { + const resultsPath = 'results/github-actions/analysis-' + context.runNumber + '.md'; + if (fs.existsSync(resultsPath)) { + const content = fs.readFileSync(resultsPath, 'utf8'); + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: `## šŸ¤– TradingAgents Analysis Results\n\n${content}` + }); + } + } catch (error) { + console.log('Could not read or post results:', error.message); + } \ No newline at end of file diff --git a/GITHUB_ACTIONS.md b/GITHUB_ACTIONS.md new file mode 100644 index 00000000..1ddf4338 --- /dev/null +++ b/GITHUB_ACTIONS.md @@ -0,0 +1,141 @@ +# GitHub Actions for TradingAgents + +This document explains how to set up and use GitHub Actions to run TradingAgents analysis automatically. + +## Overview + +We've created two GitHub Actions workflows: + +1. **Manual TradingAgents Analysis** (`.github/workflows/manual-analysis.yml`) - Simple workflow for manual triggering +2. **TradingAgents Analysis** (`.github/workflows/trading-analysis.yml`) - Advanced workflow with more configuration options + +## Setup + +### 1. Add Repository Secrets + +You need to add the following secrets to your GitHub repository: + +1. Go to your repository on GitHub +2. Navigate to **Settings** → **Secrets and variables** → **Actions** +3. Add the following secrets: + - `OPENAI_API_KEY`: Your OpenAI API key + - `FINNHUB_API_KEY`: Your FinnHub API key + +### 2. Enable GitHub Actions + +The workflows will be automatically available once you push them to your repository. You can find them in the **Actions** tab. + +## Usage + +### Manual Analysis (Recommended for beginners) + +1. Go to the **Actions** tab in your repository +2. Select **Manual TradingAgents Analysis** +3. Click **Run workflow** +4. Fill in the required fields: + - **Ticker**: Stock symbol (e.g., `NVDA`, `AAPL`, `TSLA`) + - **Date**: Analysis date in YYYY-MM-DD format (leave empty for today) +5. Click **Run workflow** + +### Advanced Analysis + +1. Go to the **Actions** tab in your repository +2. Select **TradingAgents Analysis** +3. Click **Run workflow** +4. Configure all the parameters as needed: + - **Ticker**: Stock symbol + - **Date**: Analysis date + - **Deep Think LLM**: Model for deep thinking (default: `o4-mini`) + - **Quick Think LLM**: Model for quick thinking (default: `gpt-4o-mini`) + - **Max Debate Rounds**: Number of debate rounds (default: `1`) + - **Online Tools**: Whether to use online tools (default: `true`) + - **Debug**: Enable debug mode (default: `false`) + +## Environment Variables + +The non-interactive script (`cli/non_interactive.py`) uses the following environment variables: + +### Required +- `TRADINGAGENTS_TICKER`: Stock ticker symbol to analyze +- `OPENAI_API_KEY`: Your OpenAI API key +- `FINNHUB_API_KEY`: Your FinnHub API key + +### Optional +- `TRADINGAGENTS_DATE`: Analysis date (default: today) +- `TRADINGAGENTS_DEEP_THINK_LLM`: Deep thinking LLM model (default: `o4-mini`) +- `TRADINGAGENTS_QUICK_THINK_LLM`: Quick thinking LLM model (default: `gpt-4o-mini`) +- `TRADINGAGENTS_MAX_DEBATE_ROUNDS`: Maximum debate rounds (default: `1`) +- `TRADINGAGENTS_ONLINE_TOOLS`: Use online tools (default: `true`) +- `TRADINGAGENTS_DEBUG`: Enable debug mode (default: `false`) +- `TRADINGAGENTS_OUTPUT_PATH`: Path to save results (optional) + +## Results + +After the workflow completes: + +1. **Artifacts**: Analysis results are saved as GitHub artifacts that you can download +2. **Logs**: Full execution logs are available in the workflow run +3. **Output**: The final decision and analysis are displayed in the workflow output + +## Scheduled Runs + +The advanced workflow includes a scheduled run that executes daily at 9 AM UTC on weekdays (Monday-Friday). You can modify the schedule in the workflow file: + +```yaml +schedule: + - cron: '0 9 * * 1-5' # Daily at 9 AM UTC, Monday-Friday +``` + +## Local Testing + +You can test the non-interactive script locally: + +```bash +# Set environment variables +export OPENAI_API_KEY="your-openai-api-key" +export FINNHUB_API_KEY="your-finnhub-api-key" +export TRADINGAGENTS_TICKER="NVDA" +export TRADINGAGENTS_DATE="2024-01-15" + +# Run the analysis +python cli/non_interactive.py +``` + +## Troubleshooting + +### Common Issues + +1. **Missing API Keys**: Ensure both `OPENAI_API_KEY` and `FINNHUB_API_KEY` are set as repository secrets +2. **Invalid Ticker**: Make sure the ticker symbol is valid and exists +3. **Date Format**: Use YYYY-MM-DD format for dates +4. **API Limits**: Be aware of OpenAI and FinnHub API rate limits + +### Debug Mode + +Enable debug mode to get more detailed output: + +```yaml +TRADINGAGENTS_DEBUG: true +``` + +### Cost Optimization + +To reduce API costs: +- Use `o4-mini` and `gpt-4o-mini` models +- Set `max_debate_rounds` to `1` +- Use `online_tools: false` if you have cached data + +## Customization + +You can customize the workflows by: + +1. Modifying the workflow files in `.github/workflows/` +2. Adding new environment variables to the non-interactive script +3. Creating new workflows for specific use cases + +## Security Notes + +- Never commit API keys to your repository +- Use GitHub Secrets for sensitive information +- Consider using different API keys for testing vs production +- Monitor your API usage to avoid unexpected costs \ No newline at end of file diff --git a/README.md b/README.md index cac18691..cba54b0a 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@
-šŸš€ [TradingAgents](#tradingagents-framework) | ⚔ [Installation & CLI](#installation-and-cli) | šŸŽ¬ [Demo](https://www.youtube.com/watch?v=90gr5lwjIho) | šŸ“¦ [Package Usage](#tradingagents-package) | šŸ¤ [Contributing](#contributing) | šŸ“„ [Citation](#citation) +šŸš€ [TradingAgents](#tradingagents-framework) | ⚔ [Installation & CLI](#installation-and-cli) | šŸŽ¬ [Demo](https://www.youtube.com/watch?v=90gr5lwjIho) | šŸ“¦ [Package Usage](#tradingagents-package) | šŸ¤– [GitHub Actions](#github-actions) | šŸ¤ [Contributing](#contributing) | šŸ“„ [Citation](#citation)
@@ -192,6 +192,31 @@ print(decision) You can view the full list of configurations in `tradingagents/default_config.py`. +## GitHub Actions + +We've created GitHub Actions workflows to run TradingAgents analysis automatically. This is perfect for: + +- **Automated daily analysis** of your favorite stocks +- **CI/CD integration** for trading research +- **Non-interactive execution** in cloud environments + +### Quick Start + +1. **Add Repository Secrets**: Set `OPENAI_API_KEY` and `FINNHUB_API_KEY` in your repository settings +2. **Run Manual Analysis**: Go to Actions → Manual TradingAgents Analysis → Run workflow +3. **Configure Parameters**: Enter ticker symbol and optional date +4. **Get Results**: Download analysis results as artifacts + +### Features + +- āœ… **Manual triggering** with custom parameters +- āœ… **Scheduled daily runs** (weekdays at 9 AM UTC) +- āœ… **Artifact storage** for analysis results +- āœ… **PR integration** with automatic commenting +- āœ… **Cost optimization** with configurable models + +For detailed setup and usage instructions, see [GITHUB_ACTIONS.md](GITHUB_ACTIONS.md). + ## Contributing We welcome contributions from the community! Whether it's fixing a bug, improving documentation, or suggesting a new feature, your input helps make this project better. If you are interested in this line of research, please consider joining our open-source financial AI research community [Tauric Research](https://tauric.ai/). diff --git a/cli/non_interactive.py b/cli/non_interactive.py new file mode 100644 index 00000000..8df7f5e7 --- /dev/null +++ b/cli/non_interactive.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +""" +Non-interactive version of TradingAgents CLI for use in CI/CD environments like GitHub Actions. +This script uses environment variables for configuration instead of interactive prompts. +""" + +import os +import sys +import datetime +from pathlib import Path +from typing import Optional + +from tradingagents.graph.trading_graph import TradingAgentsGraph +from tradingagents.default_config import DEFAULT_CONFIG +from cli.models import AnalystType + + +def get_env_or_default(key: str, default: str) -> str: + """Get value from environment variable or return default.""" + return os.getenv(key, default) + + +def get_env_or_fail(key: str) -> str: + """Get value from environment variable or fail if not set.""" + value = os.getenv(key) + if not value: + raise ValueError(f"Environment variable {key} is required but not set") + return value + + +def run_non_interactive_analysis(): + """Run TradingAgents analysis with environment variable configuration.""" + + # Get required parameters from environment variables + ticker = get_env_or_fail("TRADINGAGENTS_TICKER") + analysis_date = get_env_or_default("TRADINGAGENTS_DATE", datetime.date.today().strftime("%Y-%m-%d")) + + # Get optional configuration from environment variables + deep_think_llm = get_env_or_default("TRADINGAGENTS_DEEP_THINK_LLM", "o4-mini") + quick_think_llm = get_env_or_default("TRADINGAGENTS_QUICK_THINK_LLM", "gpt-4o-mini") + max_debate_rounds = int(get_env_or_default("TRADINGAGENTS_MAX_DEBATE_ROUNDS", "1")) + online_tools = get_env_or_default("TRADINGAGENTS_ONLINE_TOOLS", "true").lower() == "true" + debug = get_env_or_default("TRADINGAGENTS_DEBUG", "false").lower() == "true" + + # Create custom configuration + config = DEFAULT_CONFIG.copy() + config["deep_think_llm"] = deep_think_llm + config["quick_think_llm"] = quick_think_llm + config["max_debate_rounds"] = max_debate_rounds + config["online_tools"] = online_tools + + print(f"šŸš€ Starting TradingAgents analysis for {ticker} on {analysis_date}") + print(f"šŸ“Š Configuration:") + print(f" - Deep Think LLM: {deep_think_llm}") + print(f" - Quick Think LLM: {quick_think_llm}") + print(f" - Max Debate Rounds: {max_debate_rounds}") + print(f" - Online Tools: {online_tools}") + print(f" - Debug Mode: {debug}") + print() + + try: + # Initialize TradingAgents with custom config + ta = TradingAgentsGraph(debug=debug, config=config) + + # Run the analysis + print("šŸ”„ Running analysis...") + _, decision = ta.propagate(ticker, analysis_date) + + print("āœ… Analysis completed successfully!") + print("\nšŸ“‹ Final Decision:") + print("=" * 50) + print(decision) + print("=" * 50) + + # Save results to file if output path is specified + output_path = os.getenv("TRADINGAGENTS_OUTPUT_PATH") + if output_path: + output_file = Path(output_path) + output_file.parent.mkdir(parents=True, exist_ok=True) + with open(output_file, 'w') as f: + f.write(f"# TradingAgents Analysis Report\n") + f.write(f"**Ticker:** {ticker}\n") + f.write(f"**Date:** {analysis_date}\n") + f.write(f"**Generated:** {datetime.datetime.now().isoformat()}\n\n") + f.write(f"## Final Decision\n\n{decision}\n") + print(f"šŸ’¾ Results saved to: {output_path}") + + return 0 + + except Exception as e: + print(f"āŒ Error during analysis: {str(e)}") + return 1 + + +if __name__ == "__main__": + # Check if required API keys are set + required_keys = ["OPENAI_API_KEY", "FINNHUB_API_KEY"] + missing_keys = [key for key in required_keys if not os.getenv(key)] + + if missing_keys: + print(f"āŒ Missing required environment variables: {', '.join(missing_keys)}") + print("Please set these environment variables before running the analysis.") + sys.exit(1) + + # Run the analysis + exit_code = run_non_interactive_analysis() + sys.exit(exit_code) \ No newline at end of file diff --git a/results/TSLA/2025-07-09/message_tool.log b/results/TSLA/2025-07-09/message_tool.log index 652d50ba..fb7bafbd 100644 --- a/results/TSLA/2025-07-09/message_tool.log +++ b/results/TSLA/2025-07-09/message_tool.log @@ -38,3 +38,4 @@ 20:07:44 [Reasoning] Continue 20:07:45 [Reasoning] 20:07:45 [Tool Call] get_fundamentals_openai(ticker=TSLA, curr_date=2025-07-09) +20:11:38 [Reasoning] I searched for discussions on Tesla (TSLA) from June 9, 2025, to July 9, 2025, but couldn't locate specific data from Fundamental.com. However, I found several analyses from other reputable sources during that period. Here's a summary of key financial metrics and insights: | Date | Source | Key Insights