From 58d7e0f154c9d0f054c22b38ba7d326b3ab56b5f Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Sun, 22 Dec 2024 00:55:56 -0800 Subject: [PATCH 1/5] Add Docker support with build and run instructions --- Dockerfile | 26 ++++++++++++++++++++++++++ README.md | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..62e77459 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM python:3.9-slim + +WORKDIR /app + +RUN apt-get update && apt-get install -y \ + curl \ + && rm -rf /var/lib/apt/lists/* + +RUN curl -sSL https://install.python-poetry.org | python3 - + +ENV PATH="${PATH}:/root/.local/bin" + +COPY pyproject.toml README.md ./ +COPY src/ ./src/ + +RUN poetry config virtualenvs.create false + +RUN poetry install --no-dev + +COPY .env* ./ + +ENV PYTHONPATH=/app +ENV PYTHONUNBUFFERED=1 + +# Default to showing help for agents.py +CMD ["python", "src/agents.py", "--help"] diff --git a/README.md b/README.md index 213ea919..a29d642a 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ By using this software, you agree to use it solely for learning purposes. - [Usage](#usage) - [Running the Hedge Fund](#running-the-hedge-fund) - [Running the Backtester](#running-the-backtester) +- [Docker](#docker) - [Project Structure](#project-structure) - [Contributing](#contributing) - [License](#license) @@ -79,7 +80,7 @@ poetry run python src/agents.py --ticker AAPL --show-reasoning You can optionally specify the start and end dates to make decisions for a specific time period. ```bash -poetry run python src/agents.py --ticker AAPL --start-date 2024-01-01 --end-date 2024-03-01 +poetry run python src/agents.py --ticker AAPL --start-date 2024-01-01 --end-date 2024-03-01 ``` ### Running the Backtester @@ -108,7 +109,35 @@ You can optionally specify the start and end dates to backtest over a specific t poetry run python src/backtester.py --ticker AAPL --start-date 2024-01-01 --end-date 2024-03-01 ``` -## Project Structure +## Docker + +You can also build and run the project using Docker. + +1. Build the Docker image: +```bash +docker build -t ai-hedge-fund . +``` + +2. Run the Hedge Fund system: +```bash +docker run -it --env-file .env ai-hedge-fund python src/agents.py --ticker AAPL +``` + +3. Run the Backtester: +```bash +docker run -it --env-file .env ai-hedge-fund python src/backtester.py --ticker AAPL +``` + +4. Run with additional options (e.g., reasoning and date range): +```bash +docker run -it --env-file .env ai-hedge-fund python src/agents.py \ +--ticker AAPL \ +--start-date 2024-01-01 \ +--end-date 2024-03-01 \ +--show-reasoning +``` + +## Project Structure ``` ai-hedge-fund/ ├── src/ @@ -131,3 +160,4 @@ ai-hedge-fund/ ## License This project is licensed under the MIT License - see the LICENSE file for details. + From b2e91dee4175e882e73a79b3595a877d88be2b70 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Sun, 22 Dec 2024 01:10:18 -0800 Subject: [PATCH 2/5] Fix handling of insider trades that have no transaction_shares --- src/agents.py | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/agents.py b/src/agents.py index 66b912b7..3071546b 100644 --- a/src/agents.py +++ b/src/agents.py @@ -354,30 +354,40 @@ def sentiment_agent(state: AgentState): # Loop through the insider trades, if transaction_shares is negative, then it is a sell, which is bearish, if positive, then it is a buy, which is bullish signals = [] for trade in insider_trades: + if trade["transaction_shares"] is None: + continue if trade["transaction_shares"] < 0: signals.append("bearish") else: signals.append("bullish") - # Determine overall signal - bullish_signals = signals.count("bullish") - bearish_signals = signals.count("bearish") - if bullish_signals > bearish_signals: - overall_signal = "bullish" - elif bearish_signals > bullish_signals: - overall_signal = "bearish" + # If no valid signals, return neutral + if not signals: + message_content = { + "signal": "neutral", + "confidence": "0%", + "reasoning": "No valid insider trading data available" + } else: - overall_signal = "neutral" + # Determine overall signal + bullish_signals = signals.count("bullish") + bearish_signals = signals.count("bearish") + if bullish_signals > bearish_signals: + overall_signal = "bullish" + elif bearish_signals > bullish_signals: + overall_signal = "bearish" + else: + overall_signal = "neutral" - # Calculate confidence level based on the proportion of indicators agreeing - total_signals = len(signals) - confidence = max(bullish_signals, bearish_signals) / total_signals + # Calculate confidence level based on the proportion of indicators agreeing + total_signals = len(signals) + confidence = max(bullish_signals, bearish_signals) / total_signals - message_content = { - "signal": overall_signal, - "confidence": f"{round(confidence * 100)}%", - "reasoning": f"Bullish signals: {bullish_signals}, Bearish signals: {bearish_signals}" - } + message_content = { + "signal": overall_signal, + "confidence": f"{round(confidence * 100)}%", + "reasoning": f"Bullish signals: {bullish_signals}, Bearish signals: {bearish_signals}" + } # Print the reasoning if the flag is set if show_reasoning: From d14772cef19431f1a4268794e487bbe47394c342 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Mon, 23 Dec 2024 11:54:21 -0800 Subject: [PATCH 3/5] Update Docker setup to use Docker Compose for easier command execution --- README.md | 28 ++++++++++------------------ docker-compose.yml | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 18 deletions(-) create mode 100644 docker-compose.yml diff --git a/README.md b/README.md index a29d642a..55498190 100644 --- a/README.md +++ b/README.md @@ -111,31 +111,23 @@ poetry run python src/backtester.py --ticker AAPL --start-date 2024-01-01 --end- ## Docker -You can also build and run the project using Docker. +You can run the project easily using Docker Compose. -1. Build the Docker image: +1. Run the agent with custom parameters: ```bash -docker build -t ai-hedge-fund . +docker compose run agent --ticker AAPL ``` -2. Run the Hedge Fund system: +2. Run the backtester with custom parameters: ```bash -docker run -it --env-file .env ai-hedge-fund python src/agents.py --ticker AAPL +docker compose run backtester --ticker AAPL ``` -3. Run the Backtester: -```bash -docker run -it --env-file .env ai-hedge-fund python src/backtester.py --ticker AAPL -``` - -4. Run with additional options (e.g., reasoning and date range): -```bash -docker run -it --env-file .env ai-hedge-fund python src/agents.py \ ---ticker AAPL \ ---start-date 2024-01-01 \ ---end-date 2024-03-01 \ ---show-reasoning -``` +Note: +- The `.env` file will be automatically loaded by Docker Compose +- Use `docker-compose up` to run with default parameters defined in docker-compose.yml +- Use `docker-compose run` to pass custom parameters - no need to specify the python command +- All arguments after the service name are passed directly to the script ## Project Structure ``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..e1022ad5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +version: '3.8' + +services: + agent: + build: + context: . + dockerfile: Dockerfile + env_file: .env + volumes: + - .:/app + entrypoint: python src/agents.py + command: --ticker AAPL + networks: + - ai-hedge-fund + + backtester: + build: + context: . + dockerfile: Dockerfile + env_file: .env + volumes: + - .:/app + entrypoint: python src/backtester.py + command: --ticker AAPL + networks: + - ai-hedge-fund + +networks: + ai-hedge-fund: + driver: bridge From ae5231dfc0dcc584922fd286f4221d4c3f29989d Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Mon, 23 Dec 2024 18:01:56 -0800 Subject: [PATCH 4/5] Add Docker workflow for publishing image and system setup --- .github/workflows/docker-publish.yml | 49 +++++++++++++++++++++++++ README.md | 54 +++++++++++++++++----------- docker-compose.yml | 8 ++--- 3 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/docker-publish.yml diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 00000000..60f85404 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,49 @@ +name: Docker + +on: + push: + branches: [ "main" ] + tags: [ 'v*.*.*' ] + pull_request: + branches: [ "main" ] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/README.md b/README.md index 55498190..f3c5c02c 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ By using this software, you agree to use it solely for learning purposes. - [Usage](#usage) - [Running the Hedge Fund](#running-the-hedge-fund) - [Running the Backtester](#running-the-backtester) -- [Docker](#docker) - [Project Structure](#project-structure) - [Contributing](#contributing) - [License](#license) @@ -45,6 +44,17 @@ git clone https://github.com/virattt/ai-hedge-fund.git cd ai-hedge-fund ``` +### System Requirements +- CPU: Any modern CPU (last 5 years) +- RAM: 2GB minimum, 4GB recommended +- Storage: 1GB free space +- Internet: Stable connection required +- No GPU required + +The system is lightweight as it primarily manages workflows between APIs (OpenAI and financial data) without running any local AI models. + +### Option 1: Local Setup + 1. Install Poetry (if not already installed): ```bash curl -sSL https://install.python-poetry.org | python3 - @@ -64,6 +74,28 @@ export OPENAI_API_KEY='your-api-key-here' # Get a key from https://platform.open export FINANCIAL_DATASETS_API_KEY='your-api-key-here' # Get a key from https://financialdatasets.ai/ ``` +### Option 2: Docker Setup + +You can either build the image locally or use our official image from GitHub Container Registry: + +#### Using the Official Image + +1. Create and configure your `.env` file as explained above. + +2. Pull and run the official image using docker compose: +```bash +# Run the trading agent +docker compose run agent --ticker AAPL + +# Run the backtester +docker compose run backtester --ticker AAPL + +# Run with custom parameters +docker compose run agent --ticker AAPL --start-date 2024-01-01 --end-date 2024-03-01 --show-reasoning +``` + +The Docker setup uses a lightweight Python 3.9 base image and installs only the required dependencies. + ## Usage ### Running the Hedge Fund @@ -109,26 +141,6 @@ You can optionally specify the start and end dates to backtest over a specific t poetry run python src/backtester.py --ticker AAPL --start-date 2024-01-01 --end-date 2024-03-01 ``` -## Docker - -You can run the project easily using Docker Compose. - -1. Run the agent with custom parameters: -```bash -docker compose run agent --ticker AAPL -``` - -2. Run the backtester with custom parameters: -```bash -docker compose run backtester --ticker AAPL -``` - -Note: -- The `.env` file will be automatically loaded by Docker Compose -- Use `docker-compose up` to run with default parameters defined in docker-compose.yml -- Use `docker-compose run` to pass custom parameters - no need to specify the python command -- All arguments after the service name are passed directly to the script - ## Project Structure ``` ai-hedge-fund/ diff --git a/docker-compose.yml b/docker-compose.yml index e1022ad5..3aa3a208 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,9 +2,7 @@ version: '3.8' services: agent: - build: - context: . - dockerfile: Dockerfile + image: ghcr.io/virattt/ai-hedge-fund:main env_file: .env volumes: - .:/app @@ -14,9 +12,7 @@ services: - ai-hedge-fund backtester: - build: - context: . - dockerfile: Dockerfile + image: ghcr.io/virattt/ai-hedge-fund:main env_file: .env volumes: - .:/app From 32dbcca5d70e678b6ca2b209b56835f2784e1078 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Mon, 23 Dec 2024 20:24:00 -0800 Subject: [PATCH 5/5] Update entrypoint to run main.py instead of agents.py --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3aa3a208..1ed1f6f4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,7 @@ services: env_file: .env volumes: - .:/app - entrypoint: python src/agents.py + entrypoint: python src/main.py command: --ticker AAPL networks: - ai-hedge-fund