Skip to content

Contributing to TradAI

Thank you for your interest in contributing to TradAI! This guide will help you get started with development and understand our code standards.


Development Setup

Prerequisites

  • Python 3.11+ (required)
  • UV package manager (installed automatically)
  • Docker & Docker Compose (for services)
  • Git (for version control)

Quick Start

# Clone the repository
git clone https://github.com/tradai-bot/tradai-uv.git
cd tradai-uv

# Run setup (installs UV, Python 3.11, dependencies, pre-commit hooks)
just setup

# Verify installation
just check

IDE Configuration

Install recommended extensions: - Python (ms-python.python) - Pylance (ms-python.vscode-pylance) - Ruff (charliermarsh.ruff)

Add to .vscode/settings.json:

{
  "python.defaultInterpreterPath": ".venv/bin/python",
  "python.analysis.typeCheckingMode": "basic",
  "editor.formatOnSave": true,
  "[python]": {
    "editor.defaultFormatter": "charliermarsh.ruff"
  },
  "ruff.lint.enable": true
}

PyCharm

  1. Set Python interpreter to .venv/bin/python
  2. Enable Ruff integration via plugin
  3. Configure Google-style docstrings

Code Standards

We follow strict coding standards to maintain quality. All standards are documented in CLAUDE.md.

Key Principles

Principle Description
SOLID Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion
DRY Don't Repeat Yourself - extract common logic
No Legacy Code Remove unused code immediately

Python Style

# CORRECT: Absolute imports, type hints, Pydantic models
from datetime import datetime
from typing import Optional, Protocol

from pydantic import BaseModel

from tradai.common.exceptions import ValidationError


class DateRange(BaseModel):
    """Date range for data queries.

    Args:
        start: Range start datetime
        end: Range end datetime
    """
    start: datetime
    end: datetime
    model_config = {"frozen": True}


class DataRepository(Protocol):
    """Protocol for data fetching."""

    def fetch_ohlcv(self, symbols: list[str]) -> dict: ...

What to Avoid

Anti-Pattern Do Instead
Relative imports (from .module) Absolute imports (from tradai.common)
@dataclass Pydantic BaseModel
class Foo(ABC) Protocol
# type: ignore Fix the type issue
except Exception: Catch specific exceptions
print() Use LoggerMixin

Formatting

We use Ruff for formatting and linting:

# Format code
just fmt

# Check linting
just lint

# Run type checking
just typecheck

Line length: 100 characters max.

Docstrings

Use Google-style docstrings:

def fetch_ohlcv(symbols: list[str], date_range: DateRange) -> OHLCVData:
    """Fetch OHLCV data from exchange.

    Args:
        symbols: Symbols to fetch (e.g., ["BTC/USDT:USDT"])
        date_range: Date range for query

    Returns:
        OHLCVData containing the fetched market data

    Raises:
        ValidationError: If inputs are invalid
        DataFetchError: If exchange API call fails
    """

Testing Requirements

Coverage Target

80% minimum coverage for all packages.

Test Structure

libs/tradai-common/
├── src/
│   └── tradai/common/
└── tests/
    ├── unit/              # Unit tests
    │   ├── test_entities.py
    │   └── test_http_client.py
    └── integration/       # Integration tests
        └── test_aws.py

Running Tests

# Run all tests
just test

# Run with coverage
just test-cov

# Run specific package
just test-package libs/tradai-data

# Run single test
uv run pytest -k "test_fetch_ohlcv"

# Run with markers
uv run pytest -m unit
uv run pytest -m integration

Test Markers

Marker Description
@pytest.mark.unit Fast unit tests
@pytest.mark.integration Integration tests (may need services)
@pytest.mark.slow Slow tests (>5s)

TDD Workflow

  1. RED: Write failing test
  2. GREEN: Minimal code to pass
  3. REFACTOR: Clean up, ensure SOLID/DRY

Pull Request Process

Branch Naming

feature/add-bollinger-bands
fix/backtest-memory-leak
docs/update-cli-reference
refactor/simplify-repository-pattern

Commit Messages

Use Conventional Commits:

feat(tradai-data): add Binance WebSocket support
fix(tradai-strategy): resolve memory leak in backtest
docs(cli): update optimization command examples
refactor(tradai-common): simplify http client retry logic
test(tradai-strategy): add preflight validation tests

PR Checklist

Before submitting:

  • [ ] just check passes (lint + typecheck + test)
  • [ ] Tests added for new functionality
  • [ ] Documentation updated if needed
  • [ ] No new # type: ignore comments
  • [ ] Commit messages follow convention
  • [ ] Branch is up to date with main

Review Process

  1. Create PR with descriptive title and summary
  2. CI checks must pass (lint, typecheck, tests)
  3. Request review from maintainers
  4. Address feedback in new commits
  5. Squash merge when approved

Documentation Updates

Running Docs Locally

# Start docs server (auto-reload)
just docs

# View at http://127.0.0.1:8000/tradai-uv/

Adding New Pages

  1. Create markdown file in docs/
  2. Add to nav: section in mkdocs.yml
  3. Test locally with just docs
  4. Submit PR with changes

Docstring Requirements

For auto-generated API docs:

  • All public classes/functions need docstrings
  • Use Google-style format
  • Include Args, Returns, Raises sections
  • Add usage examples where helpful

Workspace Structure

tradai-uv/
├── libs/                  # Shared libraries
│   ├── tradai-common/    # Base utilities
│   ├── tradai-data/      # Data fetching/storage
│   └── tradai-strategy/  # Strategy framework
├── services/             # Microservices
│   ├── backend/          # API gateway
│   ├── data-collection/  # Data sync
│   ├── strategy-service/ # Execution
│   └── mlflow/           # ML tracking
├── cli/                  # CLI aggregator
├── docs/                 # Documentation
└── infra/                # Pulumi IaC

Library Exports

Each library has a public API in __init__.py:

# libs/tradai-common/src/tradai/common/__init__.py
from tradai.common.entities import DateRange, ExchangeConfig
from tradai.common.exceptions import TradAIError, ValidationError

__all__ = [
    "DateRange",
    "ExchangeConfig",
    "TradAIError",
    "ValidationError",
]

Getting Help


License

By contributing to TradAI, you agree that your contributions will be licensed under the project's license.