# PyEventBT > PyEventBT is an open-source Python framework for event-driven backtesting and live trading on MetaTrader 5 (MT5). Install with `pip install pyeventbt`. PyEventBT lets traders develop, backtest, and deploy algorithmic trading strategies using Python — no MQL5 required. The same strategy code runs in both backtesting and live trading with zero changes. It provides a complete mock of the MT5 API, so strategies transition seamlessly from research to production. - **Repository**: https://github.com/marticastany/pyeventbt - **PyPI**: https://pypi.org/project/pyeventbt/ - **Documentation**: https://pyeventbt.com - **License**: Apache 2.0 ## Key Features - Event-driven architecture that eliminates look-ahead bias - Write once, run anywhere: same code for backtesting and live trading - Python-only: no MQL5 code needed, full Python ecosystem (Polars, NumPy, Pandas) - Multi-timeframe, multi-instrument, multi-rule strategies - Modular engines: plug in custom signal, sizing, risk, and execution logic - Built-in technical indicators: ATR, SMA, EMA, KAMA, TRIX, DeMarker, RVI, Bollinger Bands - MetaTrader 5 integration for live order execution - Built-in performance metrics and equity curve visualization ## Installation ``` pip install pyeventbt ``` Requires Python 3.12+. Windows recommended for live trading (MT5 dependency). ## Core Architecture The framework processes events through a FIFO queue: ``` BarEvent → Signal Engine (your strategy) → Sizing Engine → Risk Engine → OrderEvent → Execution Engine → FillEvent → Portfolio ``` ### Modules (accessible via the `modules` object in your strategy) - `modules.DATA_PROVIDER` — get_latest_bars(), get_latest_tick(), get_latest_bid/ask() - `modules.PORTFOLIO` — get_positions(), get_account_balance/equity(), get_number_of_strategy_open_positions_by_symbol() - `modules.EXECUTION_ENGINE` — close_all_strategy_positions(), cancel_all_strategy_pending_orders(), update_position_sl_tp() - `modules.TRADING_CONTEXT` — "BACKTEST" or "LIVE" ### Event Types - **BarEvent**: OHLCV market data for a time period - **SignalEvent**: Trading signal (BUY/SELL) — this is what your strategy creates - **OrderEvent**: Sized and risk-validated order (created automatically) - **FillEvent**: Execution confirmation (created automatically) - **ScheduledEvent**: Timer-based periodic events ### Configuration Classes - Sizing: `MinSizingConfig`, `FixedSizingConfig`, `RiskPctSizingConfig` - Risk: `PassthroughRiskConfig` (or custom via `@strategy.custom_risk_engine`) - Signal: `@strategy.custom_signal_engine` decorator for strategy logic ## Quick Example — MA Crossover Strategy ```python from pyeventbt import ( Strategy, BarEvent, SignalEvent, Modules, StrategyTimeframes, PassthroughRiskConfig, MinSizingConfig ) from pyeventbt.events.events import OrderType, SignalType from pyeventbt.indicators import SMA from datetime import datetime from decimal import Decimal strategy_id = "ma_crossover" strategy = Strategy() signal_timeframe = StrategyTimeframes.ONE_DAY @strategy.custom_signal_engine( strategy_id=strategy_id, strategy_timeframes=[signal_timeframe] ) def ma_crossover(event: BarEvent, modules: Modules): if event.timeframe != signal_timeframe: return symbol = event.symbol bars = modules.DATA_PROVIDER.get_latest_bars(symbol, signal_timeframe, 40) if bars is None or bars.height < 40: return close = bars.select('close').to_numpy().flatten() fast = SMA.compute(close, 10) slow = SMA.compute(close, 30) positions = modules.PORTFOLIO.get_number_of_strategy_open_positions_by_symbol(symbol) if fast[-1] > slow[-1] and positions['LONG'] == 0: if positions['SHORT'] > 0: modules.EXECUTION_ENGINE.close_strategy_short_positions_by_symbol(symbol) time_gen = event.datetime + signal_timeframe.to_timedelta() if modules.TRADING_CONTEXT == "BACKTEST" else datetime.now() tick = modules.DATA_PROVIDER.get_latest_tick(symbol) return [SignalEvent( symbol=symbol, time_generated=time_gen, strategy_id=strategy_id, signal_type=SignalType.BUY, order_type=OrderType.MARKET, order_price=tick['ask'], sl=Decimal('0.0'), tp=Decimal('0.0'), )] strategy.configure_predefined_sizing_engine(MinSizingConfig()) strategy.configure_predefined_risk_engine(PassthroughRiskConfig()) backtest = strategy.backtest( strategy_id=strategy_id, initial_capital=100000, symbols_to_trade=['EURUSD'], csv_dir=None, start_date=datetime(2020, 1, 1), end_date=datetime(2023, 12, 1), account_currency='USD' ) backtest.plot() ``` ## Documentation Sections - [About PyEventBT](https://pyeventbt.com/getting-started/about-pyeventbt/): Full overview, motivation, and architecture - [Installation](https://pyeventbt.com/getting-started/installation/): Setup with pip, virtual environments, verification - [Quickstart Guide](https://pyeventbt.com/getting-started/quickstart-guide/): Bollinger Bands breakout strategy walkthrough - [How It Works](https://pyeventbt.com/getting-started/how-it-works/): Event-driven architecture explained - [Data Provider](https://pyeventbt.com/modules/data-provider/): Market data access API reference - [Execution Engine](https://pyeventbt.com/modules/execution-engine/): Order execution and position management - [Portfolio](https://pyeventbt.com/modules/portfolio/): Account state, positions, and P&L tracking - [Core Architecture Reference](https://pyeventbt.com/reference/core-architecture/): Component layers and event pipeline - [Events Reference](https://pyeventbt.com/reference/events/): BarEvent, SignalEvent, OrderEvent, FillEvent specs - [MA Crossover Example](https://pyeventbt.com/strategy-examples/ma-crossover/): Beginner trend-following strategy - [Bollinger Bands Breakout](https://pyeventbt.com/strategy-examples/bollinger-bands-breakout/): Intermediate intraday breakout strategy - [Quantdle Data Integration](https://pyeventbt.com/strategy-examples/quantdle-data-integration/): External data source workflow - [Full Documentation (single file)](https://pyeventbt.com/llms-full.txt): Complete docs in plain markdown for LLM context ## Comparison with Alternatives | Feature | PyEventBT | Backtrader | Zipline | VectorBT | |---|---|---|---|---| | Event-driven | Yes | Yes | Yes | No (vectorized) | | MetaTrader 5 integration | Native | No | No | No | | Live trading | Yes (MT5) | Limited | No | No | | Same code backtest/live | Yes | No | No | N/A | | Python-only (no MQL5) | Yes | Yes | Yes | Yes | | Look-ahead bias prevention | By design | Manual | By design | Manual | | Built-in indicators | Yes | Yes | No | Yes | | Multi-timeframe | Yes | Yes | Limited | Yes | ## Common Use Cases - Backtest trading strategies on historical MT5 data with realistic event-driven simulation - Connect Python to MetaTrader 5 for live algorithmic trading - Develop multi-timeframe, multi-instrument strategies in pure Python - Transition from backtesting to live trading with zero code changes - Build custom signal engines, position sizing, and risk management logic