๐Ÿ“… April 5, 2026 python algo-trading architecture open-source backtesting

Building a Python Algo Trading Strategy Lab: How TradeSight Works Under the Hood

Most algo trading tutorials skip straight to "here's a strategy, backtest it, profit." What they leave out is the plumbing: how do you run multiple strategies simultaneously, compare them fairly, and actually learn something useful before going live?

This is a walkthrough of how TradeSight is structured โ€” the key modules, the tournament system, and how Alpaca's free paper trading API ties it together. No fluff, just the architecture.

Why Paper Trading Matters Before Going Live

The obvious answer is "don't lose real money testing." But there's a subtler reason: backtesting and live trading behave differently in ways that bite you.

Backtesting assumes perfect execution โ€” your order fills at the close price, no slippage, no market impact. In reality, your order either isn't filled or fills worse. Alpaca's paper trading API mirrors live market conditions: it enforces market hours, uses real-time prices, and simulates realistic fills. The gap between your backtest and your paper results tells you more than either one alone.

TradeSight's philosophy: Don't optimize a strategy until you've seen it fail in paper trading first. Backtests are hypothesis generation. Paper trading is validation.

Architecture Overview

The project is organized around three layers:

tradesight/
paper_trader.py โ† main entry point, manages the live loop
strategies/ โ† individual strategy classes
base.py โ† abstract base class all strategies extend
macd_crossover.py
rsi_mean_reversion.py
vwap_breakout.py
... 9 total
tournament/ โ† overnight backtest + scoring engine
runner.py โ† tournament loop, scoring, leaderboard
scorer.py โ† composite score: Sharpe, drawdown, win rate

paper_trader.py is the runtime hub. It connects to Alpaca, spawns the strategy threads, and manages position tracking. The strategies directory is where the actual logic lives โ€” each one extends a common base class that enforces a consistent interface.

The Tournament System: How 9 Strategies Compete Overnight

The tournament runs every night after market close. It backtests all 9 strategies against 30 days of historical data (pulled via yfinance), scores them on a composite metric, and flags the top performer for next-day live paper trading.

The scoring formula weights four factors:

# tournament/scorer.py (simplified)
def composite_score(backtest_result):
    sharpe = backtest_result['sharpe_ratio']
    drawdown = backtest_result['max_drawdown']
    win_rate = backtest_result['win_rate']
    profit_factor = backtest_result['profit_factor']

    # Hard disqualification
    if drawdown > 0.15:
        return -1

    # Weighted composite (weights tuned over 3 months of paper results)
    score = (sharpe * 0.40) + (win_rate * 0.30) + (profit_factor * 0.20) + ((1 - drawdown) * 0.10)
    return round(score, 4)

The tournament runs roughly 45 minutes on an M4 Mac Mini, backtesting across 12 tickers per strategy. The winner gets flagged in the database; paper_trader.py picks it up at market open.

Live Paper Trading via Alpaca API

Alpaca's paper trading environment is free and genuinely useful. You get a real API, real-time market data, and a simulated $100k portfolio that resets on demand. The alpaca-py SDK handles the heavy lifting:

# paper_trader.py (simplified connection)
from alpaca.trading.client import TradingClient
from alpaca.trading.requests import MarketOrderRequest
from alpaca.trading.enums import OrderSide, TimeInForce

client = TradingClient(
    api_key=os.getenv('ALPACA_API_KEY'),
    secret_key=os.getenv('ALPACA_SECRET_KEY'),
    paper=True  # paper=False for live โ€” the only change needed
)

def place_order(symbol, qty, side):
    order = MarketOrderRequest(
        symbol=symbol,
        qty=qty,
        side=OrderSide.BUY if side == 'buy' else OrderSide.SELL,
        time_in_force=TimeInForce.DAY
    )
    return client.submit_order(order)

The paper=True flag is the only difference between paper and live mode. When you're ready to go live, you swap in your live API keys and flip that flag. Everything else stays identical.

Current paper results (as of April 5, 2026): +8.84% portfolio return. MACD Crossover leading the tournament this week. VWAP Breakout underperforming in the current high-VIX regime.

What You Can Build on Top of It

TradeSight is intentionally minimal โ€” it's a lab, not a finished product. The architecture is designed to be extended:

The entire codebase is ~2,400 lines of Python. There's no external framework dependency beyond alpaca-py and yfinance. You can read it in an afternoon.

Getting Started

Clone the repo, get a free Alpaca paper trading account (takes 2 minutes), and you're running:

git clone https://github.com/rmbell09-lang/tradesight
cd tradesight
pip install -r requirements.txt

# Add to .env:
# ALPACA_API_KEY=your_key
# ALPACA_SECRET_KEY=your_secret

python run_paper_trader.py

The overnight tournament runs automatically via cron. First results show up the next morning in the dashboard.

โ†’ github.com/rmbell09-lang/tradesight