When you create a C# Coded Model in Quantacula, you're creating a new .NET class derived from the
UserModelBase base class. Here we'll delve into how Quantacula interacts with your model during the backtesting process. The diagram below breaks down the backtesting process into two domains, the
Backtester and your
UserModelBase. The items in
UserModelBase represent the five virtual methods you can override in your model's code to hook into the different stages of the backtesting process.
Initial Processing
The Quantacula backtester begins the process by calling the
BeginBacktest method in your model. This method is optional, but if you did provide an implementation, you should note that it will only be called once, for the first symbol in your backtest universe. This method provides you a place to initialize static variables, or perform other operations that you need to undertake one time before the backtest begins.
After calling
BeginBacktest, Quantacula calls the
Initialize method in your model, once for every symbol in the backtest universe. As described in the Quantacula help, this is where you should create the instances of any indicators or other objects you declared in your model. By this point you might begin to realize, Quantacula actually creates a new instance of your model's class for every symbol in the backtest.
Bar by Bar Processing
Quantacula then creates a synchronization object that is responsible for keeping the historical data in the backtest universe aligned during the bar by bar processing. For each bar of historical data, the synchronizer collects a list of symbols (participants) that have data for the bar currently being processed.
The per-bar processing begins by performing a
market open processing. This executes any simulated orders that were placed on the previous bar, and updating the equity and cash levels.
After processing the market open, the backtester iterates through this bar's participating symbols, and calls the
Execute method in your model for each one of them. It is within your implementation of the
Execute method that simulated trades are placed, via calls to the
PlaceTrade method.
After executing your model for each participant, the backtester perform a
market close processing. This checks to see if symbols are dropped out of dynamic universes, such as the Wealth-Data Dow 30 or Nasdaq 100, and if so, it closes any open positions in those symbols at market close. The market close processing also updates the equity curve to reflect the current values of open positions.
Post-Processing
The backtester continues the bar-by-bar processing until there is no more historical data left to process. After this stage, it calls the
Cleanup method in your model, for each of the symbols in the backtest universe.
Finally, Quantacula calls the
BacktestComplete method. If you override this method, note that it will be called only on the last symbol in the backtest universe. Here you can process any summary information you might have collected during the backtest process.
In a future post we'll see how these pieces come together and implement a model that collects performance statistics on an indicator, over all of the symbols in the backtest universe.