Skip to content

rustybt Design Differences

This document catalogues known DESIGN differences between rustybt and Backtrader. These are intentional implementation choices, not bugs.

Classification Criteria

  • DESIGN: Intentional difference in implementation approach
  • BUG: Unintentional error that needs fixing

All differences listed here are classified as DESIGN and do not require fixes.


Signal Computation (Layer 2)

DD-001: RSI Calculation Method

Status: DESIGN Affected Strategies: Momentum, Multi-Factor Framework Versions: rustybt 0.1.x, Backtrader 1.9.x

rustybt Implementation:

# Simple average of gains/losses
avg_gain = sum(gains) / period
avg_loss = sum(losses) / period
rs = avg_gain / avg_loss
rsi = 100 - (100 / (1 + rs))

Backtrader Implementation: - Uses Wilder's exponential smoothing method - Produces smoother RSI values - Industry-standard approach for RSI

Rationale: Both methods are mathematically valid RSI calculations. The simple average method is computationally simpler and easier to verify. The difference is most noticeable in the first few periods after initialization but converges over time.

User Guidance: - Expect minor RSI value differences, especially early in the data series - Signal timing may differ slightly near threshold crossings - Both implementations correctly identify overbought/oversold conditions


DD-002: MACD EMA Initialization

Status: DESIGN Affected Strategies: Multi-Factor Framework Versions: rustybt 0.1.x, Backtrader 1.9.x

rustybt Implementation:

# Initialize EMA with SMA of first 'period' values
initial_sma = sum(prices[:period]) / period
# Then apply EMA formula from there
ema = initial_sma
for price in prices[period:]:
    ema = (price - ema) * multiplier + ema

Backtrader Implementation: - May use different EMA seeding method - Different handling of initial "warm-up" period

Rationale: The EMA initialization method affects early values but converges after sufficient data. This is a common difference between financial libraries.

User Guidance: - MACD values may differ in the first ~2x slow_period bars - Signal line crossovers may occur at slightly different times - Long-running strategies show convergent behavior


Data Handling (Layer 1)

DD-003: Timestamp Precision

Status: DESIGN Affected Strategies: All Framework Versions: rustybt 0.1.x, Backtrader 1.9.x

rustybt Implementation: - Uses ISO8601 format with millisecond precision - datetime.now().isoformat(timespec="milliseconds")

Backtrader Implementation: - Uses datetime.now().isoformat() (microsecond precision)

Rationale: Timestamp precision differs but does not affect strategy logic. Millisecond precision is sufficient for backtesting purposes.

User Guidance: - Timestamps in logs may have different precision - Does not affect signal generation or order execution


Order Management (Layer 3)

DD-004: Order Sizing Rounding

Status: DESIGN Affected Strategies: All Framework Versions: rustybt 0.1.x, Backtrader 1.9.x

rustybt Implementation: - Uses target_percent directly - Fractional orders supported

Backtrader Implementation: - order_target_percent() may round to integer shares - Rounding behavior depends on broker configuration

Rationale: Order sizing differences are common between frameworks due to different broker simulation approaches. Both approaches are valid.

User Guidance: - Position sizes may differ slightly - Final portfolio values may have minor differences due to rounding - For validation, focus on signal alignment rather than exact position sizes


Summary

ID Component Affected Strategies Impact
DD-001 RSI Calculation Momentum, Multi-Factor Minor signal timing
DD-002 MACD EMA Init Multi-Factor Early period values
DD-003 Timestamp All Cosmetic only
DD-004 Order Sizing All Minor position size

All DESIGN differences have been reviewed and accepted. They do not indicate errors in the rustybt implementation.


Change Log

Date Change
2025-11-29 Initial documentation of DESIGN differences