A Python backtesting engine for trading strategies, designed for SimTrading platform.
Project description
SimTrading Engine
A robust and flexible Python backtesting engine designed for testing trading strategies with the SimTrading platform. It supports both local execution with your own data and remote execution connected to the SimTrading platform.
Project Structure
The project is organized around a few key components:
src/simtrading/
├── backtest_engine/ # Core backtesting logic
│ ├── broker/ # Broker simulation (validation, liquidation, portfolio updates)
│ ├── entities/ # Data structures (Candle, OrderIntent, Position, etc.)
│ ├── portfolio/ # Portfolio management logic
│ ├── strategy/ # Strategy interface and context
│ └── engine.py # Main event loop
├── remote/ # Remote execution components (client, provider, exporter)
└── runners/ # Entry points for running backtests (local and remote)
Core Components
Broker (BacktestBroker)
The broker simulates a real exchange. It is responsible for:
- Order Validation: Checks if you have enough cash/margin to open a position.
- Execution: Simulates order execution (currently supports MARKET orders).
- Liquidation: Monitors your margin level and liquidates positions if the maintenance margin is breached.
- Portfolio Management: Updates cash and positions based on trades and market price updates.
Engine (BacktestEngine)
The engine orchestrates the backtest. It:
- Iterates through historical data candle by candle.
- Updates the portfolio snapshot.
- Calls your strategy's
on_barmethod with the current context. - Sends your order intents to the broker for execution.
- Logs all events for analysis.
Usage
1. Installation
pip install simtrading-engine
2. Writing a Strategy
To create a strategy, you must inherit from BaseStrategy and implement the on_bar method.
from simtrading import BaseStrategy
from simtrading import OrderIntent
from simtrading import Side
class MyStrategy(BaseStrategy):
def on_bar(self, context):
# This method is called for every timestamp in the backtest
# 1. Access Data
# Get the current close price for a symbol
current_price = context.candle['BTC-USD'].close
# Get historical close prices (e.g., for moving average)
closes = context.get_series('BTC-USD', 'close', limit=20)
# 2. Check Portfolio
# Check if we are already long
if not context.is_long('BTC-USD'):
# 3. Generate Order Intents
# Buy 0.1 BTC
return [
OrderIntent(
symbol='BTC-USD',
side=Side.BUY,
quantity=0.1,
order_type='MARKET'
)
]
return [] # No action
Strategy Context (StrategyContext)
The context object passed to on_bar provides everything you need:
-
Market Data:
context.candle: Dictionary of current candles{symbol: Candle}.context.past_candles: Dictionary of historical candles.context.get_series(symbol, field, limit): Helper to get a list of values (e.g., closes).context.current_timestamp(): Current timestamp.
-
Portfolio State:
context.cash: Available cash.context.equity: Total portfolio value.context.is_long(symbol)/context.is_short(symbol): Check position direction.context.get_position(symbol): Get detailed position info.
Inputs & Outputs
- Input:
context(StrategyContext) - Output: A list of
OrderIntentobjects.
3. Running a Backtest
Local Backtest
Run a backtest on your own machine using local data.
from simtrading import run_local_backtest
from simtrading import Candle
# 1. Prepare Data
# You need a dictionary mapping symbols to lists of Candle objects
candles_data = {
'BTC-USD': [
Candle(symbol='BTC-USD', timestamp=1000, date='2023-01-01', open=100, high=110, low=90, close=105, volume=1000),
# ... more candles
]
}
# 2. Run Backtest
run_local_backtest(
initial_cash=10000.0,
strategy=MyStrategy(),
fee_rate=0.001, # 0.1% fee
margin_requirement=1.0, # 1.0 = no leverage, 0.5 = 2x leverage
candles_by_symbol=candles_data,
output_dir="my_results"
)
Remote Backtest
Run a backtest using data and configuration from the SimTrading platform.
from simtrading.runners.remote_runner import run_remote_backtest
run_remote_backtest(
backtest_id="your-backtest-id",
api_key="your-api-key",
base_url="https://simtrading.fr",
strategy=MyStrategy()
)
Data Structures
Candle
Represents a single bar of market data.
symbol: strtimestamp: intdate: stropen,high,low,close: floatvolume: float
OrderIntent
Represents a request to place an order.
symbol: strside:Side.BUYorSide.SELLquantity: float (must be positive)order_type: str (currently only 'MARKET')
PortfolioSnapshot
Represents the state of your portfolio at a specific time.
cash: Available liquidity.equity: Net worth (Cash + Unrealized PnL).positions: List of open positions.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file simtrading_engine-0.1.1.tar.gz.
File metadata
- Download URL: simtrading_engine-0.1.1.tar.gz
- Upload date:
- Size: 27.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2553d4f998ef8e66af4826dc8441dd7eac915501b4dd67a3c2fa6887cb71742c
|
|
| MD5 |
ffbee44686cbbd1786986b4f25e4e55e
|
|
| BLAKE2b-256 |
2dd2d5175625c44673e275d1f9f4c6e525c7fcc127de174d57629178af201f07
|
File details
Details for the file simtrading_engine-0.1.1-py3-none-any.whl.
File metadata
- Download URL: simtrading_engine-0.1.1-py3-none-any.whl
- Upload date:
- Size: 33.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
613423763aa6c8da6a898a9b14975de67eafeee6d0ccdbb17c4edd87c6b2fec9
|
|
| MD5 |
fd79a8380f8d06ec23eb3b69a885f41a
|
|
| BLAKE2b-256 |
404790c63aa11dd29ad8b166574dcc91bd7e790bf888b020a518cf5e6b7e4047
|