Backtest Documentation
Intent
Backtest.jl exists in order to provide a straightforward interface for performing backtests in Julia. Moreover, I (Max Holloway) really like some of the ideas from the python framework Backtrader, and I wanted to make my own (better, simpler) version of it in Julia.
Core Ideas
In order to get up and running, one only needs to know how to make a DataReader and how to fill in StrategyOptions. After that, you can run your backtest! To add to the backtest, you will need to provide what are called "user-defined functions". These functions allow one to perform behavior, such as ordering shares or calculating metrics derived from FieldOperations.
Functions
Super Important Functions
Backtest.run — Functionrun(stratoptions::StrategyOptions)::StrategyRun a backtest and obtain the completed strategy object.
Arguments
stratoptions::StrategyOptions: all of the options to be used for the backtest
Returns
Strategy: a completedStrategyobject
Backtest.StrategyOptions — MethodStrategyOptions(; kwargs...)::StrategyOptionsKeyword Arguments
Required
- datareaders::Dict{AssetId, <:AbstractDataReader}: data source for each asset
- fieldoperations::Vector{<:AbstractFieldOperation}: field operations to be performed
- start::{<:Dates.TimeType}: start time for the backtest (this is the DateTime of the first bar of data to be read; actions start one bar later)
- endtime::{<:Dates.TimeType}: end time for the backtest
Optional
numlookbackbars::Integer: number of backtest bars to store; if -1, then all data is stored; if space is an issue, this can be changed to a positive #. However, this will limit how much data can be accessed.tradinginterval::{<:Dates.TimePeriod}: how much time there is between the start of a barverbosity:Type: how much verbosity the backtest should have; INFO gives the most messages, and NOVERBOSITY gives the fewestdatadelay::{<:Dates.Period}: how much time transpires at the beginning of a bar before data is received; e.g. if this is 5 seconds, then data will bereceivedby the backtest 5 seconds after the bar starts.messagelatency::{<:Dates.Period}: how much time it takes to transmit a message to a brokerage/exchangefieldoptimeout::{<:Dates.Period}: how much time until the field operation computatio times out; note that field operations are computed before the user receives datadatetimecol::String: name of datetime columnopencol::String: name of open columnhighcol::String: name of high columnlowcol::String: name of low columnclosecol::String: name of close columnvolumecol::String: name of volume columnondataevent::Function: user-defined function that performs logic when data is receivedonorderevent::Function: user-defined function that performs logic when an order event is receivedprincipal::{<:Dates.Period}: starting amount of buying power; in many cases this will be interpreted as a starting cash value
Backtest.order! — Functionorder!(strat::Strategy, order::OT)::OrderId where {OT<:Orders.AbstractOrder}Place an order and obtain its orderid.
Arguments
strat::Strategy: the strategy object running that invokes this methodorder::{<:Orders.AbstractOrder}:
Returns
OrderId: identifier for the placed order.
Accessor Functions
Backtest.Engine.numbarsavailable — Functionnumbarsavailable(strat::Strategy)::IntegerArguments
strat::Strategy: the strategy object running that invokes this method
Returns
Integer: the number of bars available from which we can retrieve data.
Backtest.Engine.data — Functiondata(strat::Strategy, ago::Integer)::NamedArrayArguments
strat::Strategy: the strategy object running when this method is invokedago::Integer: the number of bars before the previous bar; ifago= 0, this accesses the previous bar's data
Returns
NamedArray: [assetid, fieldid]->value pairs foragobars ago.
data(strat::Strategy, ago::Integer, fieldid::FieldId)::NamedArrayArguments
strat::Strategy: the strategy object running when this method is invokedago::Integer: the number of bars before the previous bar; ifago= 0, this accesses the previous bar's datafieldid::FieldId: Note:FieldIdis an alias forString
Returns
NamedArray: [fieldid]->value pairs foragobars ago.
data(strat::Strategy, ago::Integer, assetid::AssetId, fieldid::FieldId)Arguments
strat::Strategy: the strategy object running when this method is invokedago::Integer: the number of bars before the previous bar; ifago= 0, this accesses the previous bar's dataassetid::AssetId: Note:AssetIdis an alias forStringfieldid::FieldId: Note:FieldIdis an alias forString
Returns
{<:Any}: Object associatedagobars ago with thisassetidandfieldid
data(strat::Strategy)::NamedArrayArguments
strat::Strategy: the strategy object running when this method is invoked
Returns
NamedArray: [assetid, fieldid]->value pairs for the previous bar
data(strat::Strategy, fieldid::FieldId)::NamedArrayArguments
strat::Strategy: the strategy object running when this method is invokedfieldid::FieldId: Note:FieldIdis an alias forString
Returns:
NamedArray: assetid->value pairs for the previous bar.
data(strat::Strategy, assetid::AssetId, fieldid::FieldId)Arguments
strat::Strategy: the strategy object running when this method is invokedassetid::AssetId: Note:AssetIdis an alias forStringfieldid::FieldId: Note:FieldIdis an alias forString
Returns
{<:Any}: The object associated withassetidandfieldidfor the previous bar.
Other Functions
Backtest.log — Functionlog(strat::Strategy, message::String, verbosity::Type)Write message to the console.
Arguments
strat::Strategy: the strategy object running that invokes this methodmessage::String: message to be written to consoleverbosity::Type: the verbosity level to be used; seeVerbosity Levels
Types
High-Level Types
The following are types that all users must understand when running a backtest.
Backtest.StrategyOptions — TypeOptions for running a backtest.
Backtest.Portfolio — TypeInformation about the portfolio.
Verbosity Types
These types allow users to specify how much verbosity they want in their backtests. They are ordered here from most to least verbose.
Backtest.AbstractVerbosity — TypeTop of the verbosity type hierarchy. In practice, this is not intended to be a user-facing type, however it can be used if a user wants to log every possible message in the backtest.
Backtest.INFO — TypeLog all messages at the INFO level or below. This is a lot of verbosity. Supertype: AbstractVerbosity
Backtest.TRANSACTIONS — TypeLog all messages related to transactions, and all messages at a lower level. Supertype: INFO
Backtest.WARNING — TypeLog all messages that give warnings or important information. This is very low verbosity. Supertype: TRANSACTIONS
Backtest.NOVERBOSITY — TypeLog no messages at all. Supertype: WARNING
Low-Level Types
The following are types that users should never have to access directly.
Backtest.Strategy — TypeContainer for all backtest run-time state. Strategy objects should not be modified within user-provided functions.