QSTrader is a backtesting engine for systematic trading strategies written in Python.
Unlike many other open source Python-based backtesting frameworks QSTrader implements institutional-style quantitative trading mechanics, with an emphasis on portfolio construction and risk management.
It is currently optimised for long/short cash equities (and ETF) based systematic trading strategies that rebalance on a daily, or less frequent basis. It has been extensively tested on many monthly-rebalanced tactical asset allocation strategies.
Why use QSTrader?
QSTrader comes with an extensive, well-tested suite of interchangeable systematic trading modules for simulation and backtesting of long/short cash equity strategies.
This means you can concentrate on strategy development and not infrastructure development. Here is a list of the top features that are currently supported:
A collection of single or multi-asset forecast templates that can be extended to produce complex forecasting models. Holding period return (HPR)-based "momentum" and simple moving average "trend" templates are provided as baseline examples. It is straightforward to use the built-in Alpha Models as a template for your own.
Signal generation, portfolio construction and execution are decoupled from the time iteration of the simulation engine to allow independent control of cashflows, risk reporting, rebalancing and trading. This allows portfolios to be rebalanced at a frequency independent of both signal generation and the frequency used to poll for performance/risk.
Portfolio weight optimisation and order sizing is included 'out-of-the-box'. A collection of baseline optimisers is provided including equal weight (1/N) and user-supplied static proportional asset weights.
Simulated Broker with Portfolio Accounting
The default simulated brokerage engine in QSTrader handles all asset position tracking and management, with support for multiple separate portfolios. The intent is to provide a framework for periodic and one-off cashflows such as subscriptions and withdrawals, allowing realistic simulation of investment income over long-term investment horizons. Specific brokers have associated fee models, which allow realistic simulation of commissions/fees for trades.
Price/volume data is currently supported from flat-file CSV.
An extensive collection of performance and risk statistics to enable post-simulation analytics is included. By default a 'tearsheet' visualisation is generated to determine performance 'at a glance' upon completion of a backtest. Statistics can also be exported via JSON to be consumed by other applications.
QSTrader has an extensive suite of end-to-end modules with sensible defaults. This minimises the need to customise the software if you just want to carry out a quick prototype test of some signal logic. Equally, if you wish to run a sophisticated portfolio optimisation mechanism with multiple alpha and risk models, it is easy to override the defaults with your custom logic.
QSTrader is also the backtesting system used within many of the QuantStart strategy tutorials. An elementary example of its usage can be seen in our article on a traditional 60/40 portfolio.
How does QSTrader work?
The design of QSTrader is inspired by the framework outlined within the book Inside The Black Box by Rishi K. Narang.
The user provides QSTrader with an initial schedule frequency between two dates, such as 'market close on every business day'. The backtesting engine iterates through these timestamps until a rebalance timestamp is triggered.
Upon a rebalance event an alpha model instance generates a set of asset forecast weights based on a supplied asset universe. The asset universe can be static or dynamic through time. The asset forecast weights are then fed into a portfolio construction model, utilising a supplied portfolio optimiser, that potentially modifies these weights based on the users choice of a particular portfolio construction and risk management mechanism.
The weights produced by this mechanism are then sent to an order sizer, the job of which is to convert dimensionless weights into tangible target order sizes in units of stock. This gives the desired target portfolio that the strategy wishes to hold.
The desired target portfolio is then compared against the current portfolio at the simulated broker. Any differences between the target and current portfolio generate rebalancing trades that push the current portfolio towards the desired portfolio. This process is then run iteratively on every desired rebalance period.
Separation of Concerns
Crucially, the schedule of the simulation as a whole is carried out independently of the portfolio construction rebalance schedule.
This provides the ability, say, to determine daily or intraday performance even on a strategy that only rebalances once a month. Similarly this functionality can provide higher-frequency intraday performance and exposure updates on a strategy that may only trade once per day.
This mechanism also allows for cashflows and corporate actions to be applied when they actually occurred historically.
It is the task of the broker engine to keep track of the cash, asset positions and portfolio state at all times in the simulation process. This allows a clean separation between target portfolio generation logic and portfolio cashflows and accounting.
QSTrader contains sensible, conservative default implementations for all of the above behaviour. This allows useful backtests to be run with minimal customisation beyond specification of alpha and risk models. It also allows straightforward customisation for those who wish to develop bespoke behaviour for any module in the system.
Now that the basic approach of QSTrader has been outlined the next step is to install QSTrader and run a simple backtest.