Skip to content

Strategy Development Lifecycle

Complete guide for developing, testing, and deploying trading strategies with TradAI.

Lifecycle Overview

┌───────────┐   ┌──────────┐   ┌───────┐   ┌──────────┐   ┌──────────┐
│  Create   │ → │ Develop  │ → │ Test  │ → │ Backtest │ → │ Register │
└───────────┘   └──────────┘   └───────┘   └──────────┘   └──────────┘
┌───────────┐   ┌──────────┐   ┌───────────┐   ┌───────┐      │
│  Deploy   │ ← │ Promote  │ ← │ A/B Test  │ ← │ Stage │ ← ───┘
└───────────┘   └──────────┘   └───────────┘   └───────┘

Phase 1: Create Strategy

Repository Selection

Repository Purpose When to Use
tradai-uv Platform development Testing framework, infrastructure
tradai-strategies Production strategies Real trading strategies

Creating in tradai-strategies

# Navigate to strategies repo
cd ../tradai-strategies

# Login to CodeArtifact (for tradai-strategy package)
just codeartifact-login  # 12-hour token

# Quick creation
just new MomentumStrategy

# Interactive creation (recommended)
just new-interactive

# ML-enabled strategy
just new-ml TrendMLStrategy

Interactive Wizard Options

Strategy name: MomentumStrategy
Timeframe: 1h
Category (trend/momentum/mean-reversion/breakout): momentum
Enable short positions? (y/n): y
Enable FreqAI? (y/n): n

Generated Structure

momentum_strategy/
├── src/momentum_strategy/
│   ├── __init__.py
│   ├── strategy.py          # Main strategy class
│   ├── indicators.py        # Custom indicators (optional)
│   ├── signals.py           # Signal generation (optional)
│   └── py.typed
├── tests/
│   ├── __init__.py
│   └── test_strategy.py     # Unit tests
├── configs/
│   ├── backtest.json        # Backtest configuration
│   ├── live.json            # Live trading config
│   └── freqai_training.json # ML training config (if ML)
├── Dockerfile               # Container build
├── pyproject.toml           # Package definition
├── tradai.yaml              # TradAI metadata
└── README.md                # Strategy documentation

Phase 2: Develop Strategy

Required Implementation

Every strategy must extend TradAIStrategy and implement these methods:

from tradai.strategy import TradAIStrategy, StrategyMetadata
from tradai.strategy.enums import StrategyCategory

class MomentumStrategy(TradAIStrategy):
    """Momentum-based trading strategy."""

    # Freqtrade required attributes
    timeframe = '1h'
    stoploss = -0.08
    trailing_stop = True
    trailing_stop_positive = 0.01
    trailing_stop_positive_offset = 0.02

    # TradAI REQUIRED: Metadata
    def get_metadata(self) -> StrategyMetadata:
        return StrategyMetadata(
            name="MomentumStrategy",
            version="1.0.0",
            description="RSI-based momentum strategy",
            timeframe=self.timeframe,
            category=StrategyCategory.MOMENTUM,
            tags=["rsi", "momentum", "btc"],
        )

    # Freqtrade REQUIRED: Calculate indicators
    def populate_indicators(self, dataframe, metadata):
        dataframe['rsi'] = ta.RSI(dataframe['close'], timeperiod=14)
        dataframe['ema_fast'] = ta.EMA(dataframe['close'], timeperiod=12)
        dataframe['ema_slow'] = ta.EMA(dataframe['close'], timeperiod=26)
        return dataframe

    # Freqtrade REQUIRED: Define entry signals
    def populate_entry_trend(self, dataframe, metadata):
        # Long entry
        dataframe.loc[
            (dataframe['rsi'] < 30) &
            (dataframe['ema_fast'] > dataframe['ema_slow']),
            'enter_long'
        ] = 1

        # Short entry (if enabled)
        dataframe.loc[
            (dataframe['rsi'] > 70) &
            (dataframe['ema_fast'] < dataframe['ema_slow']),
            'enter_short'
        ] = 1

        return dataframe

    # Freqtrade REQUIRED: Define exit signals
    def populate_exit_trend(self, dataframe, metadata):
        dataframe.loc[
            (dataframe['rsi'] > 70),
            'exit_long'
        ] = 1

        dataframe.loc[
            (dataframe['rsi'] < 30),
            'exit_short'
        ] = 1

        return dataframe

Strategy Categories

Category Use Case Typical Timeframe
TREND_FOLLOWING Riding directional moves 1h, 4h, 1d
MOMENTUM Quick momentum captures 15m, 1h
MEAN_REVERSION Fading extreme moves 1h, 4h
BREAKOUT Range expansion 15m, 1h
ARBITRAGE Price discrepancies 1m

Note: Categories map to StrategyCategory enum in tradai.strategy.enums.

ML-Enabled Strategies (FreqAI)

For ML strategies, implement additional methods:

class TrendMLStrategy(TradAIStrategy):
    """ML-enhanced trend following strategy."""

    def feature_engineering_expand_all(self, dataframe, **kwargs):
        """Create features for ML model."""
        dataframe['rsi'] = ta.RSI(dataframe['close'])
        dataframe['macd'] = ta.MACD(dataframe['close'])['macd']
        # Add more features...
        return dataframe

    def feature_engineering_expand_basic(self, dataframe, **kwargs):
        """Basic features using %change."""
        dataframe['pct_change'] = dataframe['close'].pct_change()
        return dataframe

Phase 3: Test Strategy

Unit Tests

# Run strategy tests
just test momentum-strategy

# Run with verbose output
just test momentum-strategy -v

# Run specific test
just test momentum-strategy -k "test_metadata"

Test Structure

# tests/test_strategy.py
import pytest
from momentum_strategy.strategy import MomentumStrategy

def test_metadata():
    """Test strategy metadata is valid."""
    strategy = MomentumStrategy({})
    metadata = strategy.get_metadata()

    assert metadata.name == "MomentumStrategy"
    assert metadata.version == "1.0.0"
    assert metadata.timeframe == "1h"

def test_indicators(sample_dataframe):
    """Test indicators are populated."""
    strategy = MomentumStrategy({})
    result = strategy.populate_indicators(sample_dataframe, {})

    assert 'rsi' in result.columns
    assert 'ema_fast' in result.columns
    assert 'ema_slow' in result.columns

def test_entry_signals(sample_dataframe_with_indicators):
    """Test entry signals are generated."""
    strategy = MomentumStrategy({})
    result = strategy.populate_entry_trend(sample_dataframe_with_indicators, {})

    assert 'enter_long' in result.columns
    assert result['enter_long'].sum() > 0  # At least some signals

Lint and Type Check

# Full lint check
just lint momentum-strategy

# Individual checks
uv run ruff check momentum_strategy/
uv run mypy momentum_strategy/

Phase 4: Backtest

Smoke Backtest (Quick Validation)

# 30-day quick test
just backtest-smoke momentum-strategy

Full Backtest

# Full backtest with default timerange
just backtest-full momentum-strategy

# Custom timerange
just backtest-full momentum-strategy --timerange 20240101-20241201

# Multiple pairs
just backtest-full momentum-strategy --pairs "BTC/USDT:USDT,ETH/USDT:USDT"

Via API

# Submit backtest
curl -X POST http://localhost:8000/api/v1/backtests \
  -H "Content-Type: application/json" \
  -d '{
    "config": {
      "strategy": "MomentumStrategy",
      "pairs": ["BTC/USDT:USDT"],
      "timeframe": "1h",
      "date_range": {
        "start": "2024-01-01T00:00:00Z",
        "end": "2024-12-01T00:00:00Z"
      },
      "stake_amount": 100.0,
      "dry_run_wallet": 10000.0
    },
    "experiment_name": "momentum-v1-btc",
    "priority": 5
  }'

# Check status
curl http://localhost:8000/api/v1/backtests/${JOB_ID} | jq

Quality Thresholds

Metric Minimum Target
Sharpe Ratio > 1.0 > 1.5
Profit Factor > 1.2 > 1.5
Max Drawdown < 20% < 15%
Win Rate > 40% > 50%
Total Trades > 50 > 100

Phase 5: Register

Automatic Registration (CI/CD)

When you tag a release, CI automatically: 1. Runs full backtest 2. Builds Docker image 3. Pushes to ECR 4. Registers to MLflow Model Registry

# Tag release
git tag momentum-strategy-v1.0.0
git push --tags

Manual Registration

# Via CLI
tradai strategy register MomentumStrategy \
  --backtest-run-id mlflow_run_id_here \
  --docker-image-uri 123456789.dkr.ecr.us-east-1.amazonaws.com/momentum-strategy:v1.0.0

# Via API
curl -X POST http://localhost:8003/api/v1/strategies/MomentumStrategy/register \
  -H "Content-Type: application/json" \
  -d '{
    "backtest_run_id": "mlflow_run_id_here",
    "docker_image_uri": "ecr_image_uri_here",
    "description": "Initial release",
    "thresholds": {
      "min_sharpe": 1.0,
      "min_profit_factor": 1.2,
      "max_drawdown": 20.0
    }
  }'

Phase 6: Stage

Stage the strategy for validation testing (dry-run environment).

# Via CLI
tradai strategy stage MomentumStrategy --version 1

# Via API
curl -X POST http://localhost:8000/api/v1/strategies/MomentumStrategy/stage \
  -H "Content-Type: application/json" \
  -d '{"version": "1"}'

Staging Validation

Run the strategy in dry-run mode for 7 days: - Monitor for errors - Validate signal generation - Check resource usage


Phase 7: A/B Test (Optional)

Compare new version against existing champion.

# Create A/B test
curl -X POST http://localhost:8003/api/v1/models/MomentumStrategy/challenges \
  -H "Content-Type: application/json" \
  -d '{
    "champion_version": "1",
    "challenger_version": "2",
    "min_trades": 100,
    "max_duration_hours": 168,
    "enable_canary": true
  }'

# Check results
curl http://localhost:8003/api/v1/challenges/${CHALLENGE_ID}/evaluate | jq

Traffic Split (Canary)

Stage Champion Challenger
1 95% 5%
2 90% 10%
3 75% 25%
Final 50% 50%

Phase 8: Promote

Promote the strategy to Production.

# Via CLI
tradai strategy promote MomentumStrategy --version 2

# Via API
curl -X POST http://localhost:8000/api/v1/strategies/MomentumStrategy/promote \
  -H "Content-Type: application/json" \
  -d '{
    "version": "2",
    "archive_previous": true,
    "skip_validation": false
  }'

Promotion Requirements

  • [ ] Staging validation passed (7 days)
  • [ ] A/B test results positive (if run)
  • [ ] Quality thresholds met
  • [ ] No critical errors in logs
  • [ ] Manual approval (if required)

Phase 9: Deploy

Deploy the strategy to live trading.

# Deploy to ECS
tradai deploy strategy momentum-strategy \
  --env prod \
  --version v1.0.0 \
  --mode dry-run  # or 'live'

# Via API
curl -X POST http://localhost:8000/api/v1/strategies/MomentumStrategy/run \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "dry-run",
    "timeframe": "1h",
    "symbols": ["BTC/USDT:USDT"],
    "config_overrides": {
      "stake_amount": 100
    }
  }'

Monitoring

# List running instances
curl http://localhost:8000/api/v1/strategies/MomentumStrategy/instances | jq

# View logs
curl http://localhost:8000/api/v1/strategies/MomentumStrategy/instances/${ID}/logs | jq

# Stop instance
curl -X POST http://localhost:8000/api/v1/strategies/MomentumStrategy/instances/${ID}/stop

Version Management

Semantic Versioning

<major>.<minor>.<patch>

1.0.0 - Initial release
1.1.0 - New feature (backward compatible)
1.1.1 - Bug fix
2.0.0 - Breaking change

Tagging Convention

# Format: <strategy-slug>-v<version>
git tag momentum-strategy-v1.0.0
git tag trend-ml-v2.1.3

Model Registry Stages

Stage Description Use
None Just registered Initial state
Staging Validation testing Dry-run environment
Production Live trading Real capital
Archived Deprecated Rollback candidate

Rollback

If issues are detected in production:

# Via CLI
tradai strategy rollback MomentumStrategy --version 1

# Via API
curl -X POST http://localhost:8000/api/v1/models/MomentumStrategy/rollback \
  -H "Content-Type: application/json" \
  -d '{
    "target_version": "1",
    "dry_run": false
  }'