Skip to content

Latest commit

 

History

History
149 lines (105 loc) · 5.41 KB

File metadata and controls

149 lines (105 loc) · 5.41 KB

Contributing to alpaca-trader

Thanks for your interest in contributing to alpaca-trader. This document covers development setup, code standards, and the review process.

Development Setup

  1. Clone the repo and install dependencies:

    git clone https://github.com/costajohnt/alpaca-trader.git
    cd alpaca-trader
    uv sync
  2. Configure environment variables:

    cp .env.example .env

    Fill in your API keys in .env. At minimum you need Alpaca credentials. See .env.example for all available options.

  3. Always paper trade first:

    # In your .env file — this must be set before running any trading scripts
    ALPACA_PAPER=true

    Never run against a live account during development. All testing and development must use Alpaca's paper trading environment.

  4. Set up pre-commit hooks:

    pre-commit install

    This runs Ruff linting and format checks automatically on every commit.

Branch Workflow

  • Never commit directly to main. Always create a feature branch.
  • Use descriptive kebab-case branch names:
    • add-earnings-guard
    • fix-trailing-stop-calculation
    • update-sector-mappings
  • Pull requests require CI to pass (lint + tests) before merge.
  • Keep PRs focused on a single concern. Split large changes into smaller PRs when possible.

Code Style

This project uses Ruff for linting and formatting, configured in pyproject.toml.

  • Line length: 120 characters
  • Target version: Python 3.14+
  • Type hints: Use full type hints with modern Python 3.14+ syntax
  • Lint rules: E, F, W, I (pyflakes, pycodestyle, isort)

Structured Logging

Always use the project's structured logging — never bare print() for warnings, errors, or operational messages:

from strategies.log import get_logger

logger = get_logger(__name__)

logger.info("Processing %s", ticker)
logger.warning("Skipping %s — insufficient data", ticker)
logger.error("API call failed for %s: %s", ticker, err)

Running the Linter Manually

uv run ruff check .          # lint
uv run ruff format --check . # format check
uv run ruff check --fix .    # auto-fix lint issues
uv run ruff format .         # auto-format

Testing Requirements

Running Tests

uv run python -m pytest tests/ -v

With coverage:

uv run python -m pytest tests/ -v --cov=strategies --cov=scripts --cov-report=term-missing --cov-fail-under=58

Coverage Thresholds

  • Overall minimum: 58% (CI enforced)
  • strategies/ package: aim for ~78%+
  • Branch coverage is enabled — both paths of conditionals should be tested

Writing Tests

  • Place tests in tests/ with filenames matching test_*.py
  • Test files for strategies/foo.py should be named tests/test_foo.py
  • Test files for scripts/bar.py should be named tests/test_bar.py
  • Mock external API calls (Alpaca, Finnhub, OpenRouter, yfinance) — tests must not make real network requests

Safety-Critical Files

The following files must not be modified without careful review and discussion. These are core safety mechanisms that protect against financial loss:

File Purpose
strategies/risk_guard.py Portfolio-level kill switch (daily loss + drawdown limits)
strategies/resilience.py API retry logic with exponential backoff + circuit breaker
scripts/strategy_agent.py Autonomous strategy improvement agent
scripts/agent_tools.py Agent safety constraints (hardcoded floors, no-touch list)
tests/ All test files
.github/workflows/ CI and deployment pipelines

If your change touches any of these files, call it out explicitly in your PR description and explain why the change is necessary.

Trading Safety Conventions

These are non-negotiable safety rules for any code that interacts with order execution:

  1. Always paper trade first. Set ALPACA_PAPER=true in .env. Never test against a live account.
  2. Never exceed 5% position size. No single position may exceed 5% of account equity. This is enforced in strategies/sizing.py.
  3. All changes must pass backtesting. Run uv run python scripts/pipeline_backtest.py to validate that strategy changes do not degrade performance (Sharpe ratio must remain >= 0.3).
  4. Respect sector guard limits. Maximum 3 positions / 40% exposure per known sector; 5 positions / 50% for Unknown sector.
  5. Strategies produce signals; execution is separate. Keep signal generation and order execution as distinct concerns.
  6. 4-layer safety on all entries. Technical triggers are necessary but not sufficient — fundamentals, sentiment, and insider signals can each veto a trade.

PR Checklist

Before submitting a pull request, confirm that:

  • I created a feature branch (not committing to main)
  • My code passes uv run ruff check . with no errors
  • My code passes uv run ruff format --check . with no errors
  • I added or updated tests for my changes
  • All tests pass: uv run python -m pytest tests/ -v
  • Coverage remains at or above 58%
  • I used structured logging (get_logger) instead of print()
  • I did not modify safety-critical files without discussion
  • If touching trading logic: I ran backtesting to validate the change
  • If touching position sizing: I confirmed the 5% cap is respected
  • My PR description explains what changed and why