Skip to content

falconfx/atlas

Repository files navigation

ATLAS

Modular quantitative research and trading lab.

Pipeline: idea → research → backtest → walk-forward → paper → (live)

Nothing enters paper trading without passing a promotion gate. LLMs assist research only. Execution is deterministic.


Prerequisites

  • Python 3.10+
  • uvcurl -LsSf https://astral.sh/uv/install.sh | sh
  • Docker + Docker Compose (for Freqtrade)
  • make

Quick Start (laptop)

# 1. Clone and enter the repo
git clone <your-private-repo-url> atlas
cd atlas

# 2. First-time setup — installs all workspace packages
make setup

# 3. Download market data (180 days BTC/USDT + ETH/USDT)
make data-download

# 4a. Screening backtest (full-window, no IS/OOS split)
make backtest

# 4b. Walk-forward validation (proper IS/OOS separation)
atlas backtest walk-forward ema_cross --symbol BTC/USDT --timeframe 1h \
    --method rolling --is-days 60 --oos-days 30 --test-ratio 0.2

# 5. View results
make results
atlas backtest wf-results

CLI Reference

atlas --help

atlas data download BTC/USDT --days 180
atlas data list

atlas strategies list

# Screening (full-window, no IS/OOS split — quick hypothesis filter only)
atlas backtest run ema_cross --symbol BTC/USDT --timeframe 1h
atlas backtest run ema_cross --no-gate          # skip screening gate
atlas backtest results
atlas backtest results --strategy ema_cross --status passed

# Walk-forward validation (IS/OOS separation — required before paper promotion)
atlas backtest walk-forward ema_cross --symbol BTC/USDT --timeframe 1h
atlas backtest walk-forward ema_cross --method anchored --is-days 90 --oos-days 30
atlas backtest walk-forward ema_cross --no-gate     # skip WF gate
atlas backtest wf-results
atlas backtest wf-results --strategy ema_cross --status passed

atlas tracker add-hypothesis "EMA cross works in trending markets" \
    --rationale "Classic momentum signal" \
    --source "Investopedia" \
    --tags "momentum,ema"
atlas tracker list-hypotheses

Repo Tree

atlas/
├── Makefile
├── pyproject.toml              # uv workspace root
├── config.yaml                 # default config (committed)
├── .env.example                # env var template
├── docker-compose.yml          # server stack
├── docker-compose.dev.yml      # laptop overrides (backtest mode)
│
├── packages/
│   ├── atlas_core/             # config, logging, gates (PromotionGate, WalkForwardGate)
│   ├── atlas_data/             # OHLCV ingestion (CCXT) + SQLite store
│   ├── atlas_strategies/       # strategy interface, registry, examples
│   ├── atlas_backtest/
│   │   ├── runner.py           # SimpleVectorizedRunner (screening only)
│   │   ├── splits.py           # TimeSeriesSplitter — IS/OOS fold windows
│   │   ├── walk_forward.py     # WalkForwardRunner, FoldResult, WalkForwardResult
│   │   └── result.py           # BacktestResult dataclass
│   └── atlas_tracker/          # experiment tracker (SQLite → Postgres)
│                               # BacktestRun + WalkForwardRun persistence
│
├── cli/
│   └── atlas_cli/              # Typer CLI entrypoint
│
├── services/
│   └── freqtrade/
│       ├── Dockerfile
│       ├── config/             # Freqtrade configs (dry-run, backtest)
│       └── strategies/v1/      # Freqtrade IStrategy implementations
│
├── data/                       # gitignored at runtime; .gitkeep only
└── tests/unit/
    ├── test_splits.py          # TimeSeriesSplitter unit tests
    └── test_walk_forward.py    # WalkForwardRunner + WalkForwardGate tests

Configuration

Config is loaded in priority order (highest wins):

  1. ATLAS_* environment variables
  2. .env file
  3. config.yaml
  4. Field defaults
cp .env.example .env
# Edit .env as needed

Key config fields in config.yaml:

Field Default Description
exchange binance CCXT exchange ID
default_pairs [BTC/USDT, ETH/USDT] Pairs to download
gate_min_sharpe 0.5 Minimum OOS Sharpe for Gate 1
gate_max_drawdown 0.25 Maximum drawdown for Gate 1
gate_min_trades 30 Minimum trade count for Gate 1
gate_max_params 10 Maximum free parameters

Docker (Freqtrade)

# Paper trading (dry-run, server)
make docker-up
# → FreqUI at http://localhost:8080  (user: atlas, pass: see config.json)

# Freqtrade backtest via Docker (laptop)
make docker-dev

# Logs
make docker-logs

Before running Docker: change the jwt_secret_key and password fields in services/freqtrade/config/config.json.


Promotion Gates

Gate 1: Screening → Walk-Forward Candidate (PromotionGate)

Applied to full-window backtest results. A coarse filter — passing this gate does NOT mean a strategy is ready for paper trading.

Check Threshold
Full-window Sharpe ratio ≥ 0.5
Max drawdown ≤ 25%
Trade count ≥ 30
Free parameters ≤ 10

Gate 2: Walk-Forward → Paper Candidate (WalkForwardGate)

Applied to OOS (out-of-sample) metrics only. All checks must pass. The is_oos_degradation check catches catastrophic overfitting.

Check Threshold
Mean OOS Sharpe ≥ 0.4
Mean OOS drawdown ≤ 30%
Fold count ≥ 3
Mean OOS trades/fold ≥ 10
IS/OOS Sharpe ratio ≥ 0.4

Thresholds are hardcoded in gates.py. Lower them only with justification.


Running Tests

make test        # unit tests
make test-cov    # with coverage report

Adding a New Strategy

  1. Create packages/atlas_strategies/atlas_strategies/your_strategy.py:
from atlas_strategies.base import BaseStrategy
from atlas_strategies.registry import registry

@registry.register
class MyStrategy(BaseStrategy):
    NAME = "my_strategy"
    VERSION = "1.0.0"
    DESCRIPTION = "..."

    def default_params(self):
        return {"period": 14}

    def generate_signals(self, df):
        df = df.copy()
        # ... add indicators and signal/crossover columns
        return df
  1. Import it in atlas_strategies/examples/__init__.py (or a new module).
  2. Test: atlas backtest run my_strategy

For Freqtrade integration, also create the IStrategy version in services/freqtrade/strategies/v1/.


Phase Roadmap

Phase Focus Status
0 Foundation: repo, data, vectorized screening backtest, experiment tracker Done
1 Walk-forward validation: IS/OOS splits, WalkForwardRunner, WalkForwardGate Current
2 Freqtrade backtest wrapper (rigorous OOS), full walk-forward harness Next
3 Paper trading 24/7, monitoring dashboard Planned
4 Live trading (strict gate required) Future

Honest current status (Phase 1): Walk-forward uses SimpleVectorizedRunner internally — long-only, flat fee, no slippage. The IS/OOS split is real and the hold-out logic is correct. The OOS metrics are meaningful as a relative signal (strategy A vs B) but not realistic enough for absolute promotion decisions. FreqtradeRunner (Phase 2) will replace the inner runner for that.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors