Tradetropy¶
A professional backtesting and live trading framework for algorithmic trading strategies, with first-class support for footprint analysis and market microstructure.
Write a strategy once and run it unchanged across backtest, live and
replay - the engine differences are a transport detail behind the same
Strategy API.
Features¶
- Backtesting engine - high-performance backtesting over candles or ticks with realistic order simulation.
- Live trading - real-time execution over WebSockets (CCXT Pro) and MT5, with a single-writer, event-driven engine.
- Order flow and footprint - large trades, Deep Trades (L2/L3 absorption, sweeps), cumulative delta, COT, volume profile and liquidity overlays.
- Indicator library - the classic studies (SMA, EMA, MACD, RSI, Bollinger, ...) plus market-structure tools, all through one declarative contract.
- Optimization and pools - parameter optimization and parallel backtests.
- Monte Carlo robustness - confidence intervals, probability of loss, risk of ruin and a composite robustness score.
- Data management - efficient candle, tick and order-book handling with
NumPy
.npz/ CSV IO built in (Parquet and HDF5 optional), plus bundled sample datasets.
Install¶
The base install already includes everything you need for backtesting, plotting and data IO. Broker integrations and Parquet are optional extras - see Installation.
A first backtest¶
Every loader in tradetropy.datasets returns ready-to-use data, so you can run a
strategy without downloading anything. The Strategy tab below is a complete,
copy-paste-runnable backtest; the Results tab is its output; and the chart
underneath is generated from that very run - scroll to zoom, drag to pan.
from tradetropy import BacktestEngine, Strategy
from tradetropy.datasets import load_goog_1d
from tradetropy.signal import Signal
from tradetropy.ta import SMA
class SmaCross(Strategy):
"""Go long on a fast/slow SMA crossover, flatten on the crossunder."""
def init(self):
self.goog = self.subscribe_ohlc('GOOG', '1d', window_size=200)
self.fast = self.add_indicator(self.goog.close, SMA(10))
self.slow = self.add_indicator(self.goog.close, SMA(30))
self.signal = Signal('partial')
def on_data(self):
if self.signal.crossover(self.fast, self.slow):
if not self.sesh.positions('GOOG'):
self.sesh.buy('GOOG', volume=10)
elif self.signal.crossunder(self.fast, self.slow):
for pos in self.sesh.positions('GOOG'):
self.sesh.position_close(pos.ticket)
bt = BacktestEngine.by_klines(SmaCross(), data=(load_goog_1d(),))
bt.run()
print(bt.stats)
Start 2020-01-02 00:00:00+00:00
End 2021-03-11 00:00:00+00:00
Duration 434 days 00:00:00
Exposure Time [%] 46.7742
Equity Final [$] 10237.2
Equity Peak [$] 10244.0
Return [%] 2.372
Return (Ann.) [%] 1.9925
Volatility (Ann.) [%] 1.9296
Sharpe Ratio 1.0336
Sortino Ratio 1.649
Calmar Ratio 1.448
Max. Drawdown [%] -1.3761
Avg. Drawdown [%] -0.264
Max. Drawdown Duration 90 days 00:00:00
Avg. Drawdown Duration 14 days 18:56:50.526000
# Trades 4
# Trades Long 4
# Trades Short 0
Win Rate [%] 75.0
Best Trade [%] 12.8583
Worst Trade [%] -5.1689
Avg. Trade [%] 4.7942
Max. Trade Duration 76 days 00:00:00
Avg. Trade Duration 50 days 18:00:00
Profit Factor 4.2129
Expectancy [%] 4.7942
SQN 1.284
Total Commissions [$] 0.0
See more in the Examples.
Where to go next¶
- New here? Read the Quickstart.
- Learn the model in Core concepts.
- Load, resample and save data in Working with data.
- Browse the full API reference.