Trader

Trading.TraderType
Trader(broker::AbstractBroker; strategies = Strategy[])

This is the heart of the entire framework. It holds all the data, systems and references to runtime tasks. It can be constructed with an AbstractBroker and potentially a set of Strategies and starting time.

Upon construction with a realtime broker, the Portfolio will be filled out with the account information retrieved through the broker's API.

Default Systems

There are a set of default systems that facilitate handling trade orders and other bookkeeping tasks. These are StrategyRunner, Purchaser, Seller, Filler, SnapShotter, Timer and DayCloser.

Runtime and Control

After calling start on the Trader, a couple of tasks will start (multithreaded): Aside from this main_task there are two other tasks:

  • main_task: runs the Core Systems in sequence. This includes StrategyRunner which executes the Strategies
  • trading_task: streams in portfolio and order updates
  • data_task: streams in updates to the registered assets and updates their AssetLedgers

Aside from start there are some other functions to control the runtime:

AbstractLedger interface

Trader is a subtype of the AbstractLedger type defined in Overseer.jl, meaning that it can be extended by adding more Systems and Components to it. This lies at the heart of the extreme extensibility of this framework. You can think of the current implementation as one working example of an algorithmic trader implementation, but it can be tuned and tweaked with all the freedom.

source
Trading.BackTesterFunction
BackTester(broker::HistoricalBroker;
           dt = Minute(1),
           start    = current_time() - dt*1000,
           stop     = current_time(),
           cash     = 1e6,
           only_day = true)

This creates a Trader and adds some additional functionality to perform a backtest. Since behind the scenes it really is just a tweaked Trader, backtesting mimics the true behavior of the algorithm/strategy if it were running in realtime. By using a HistoricalBroker, the main difference is that the datastreams are replaced with historical data, as are the behavior of current_price and current_time.

See reset! to be able to rerun a BackTester

Keyword arguments

  • dt: the timestep or granularity of the data. This will also be the tickrate of the main_task of the Trader.
  • start: the starting time of the backtest
  • stop: the stopping time of the backtest
  • cash: the starting cash
  • only_day: whether the backtest should only be ran during the day. This mainly improves performance.
source

Performance Analysis

Trading.sharpeFunction
sharpe(t::Trader, period::Function=day; risk_free = 0.0)

Calculates the Sharpe ratio of a Trader. The Sharpe ratio is a measure of risk-adjusted return, and is defined as the average excess return earned over the risk-free rate per unit of volatility or total risk (i.e. the standard deviation of the returns).

risk_free: the risk-free rate to use as a baseline for the Sharpe ratio calculation. The risk-free rate represents the return an investor can earn from a risk-free investment, such as a Treasury bill. The default value is 0.0, representing a risk-free rate of 0%.

source
Trading.downside_riskFunction
downside_risk(t::Trader, period::Function=day; required_return=0.0)

Calculates the downside risk of a Trader. Downside risk is a measure of the potential loss of an investment, and is defined as the standard deviation of returns below a certain threshold: required_return.

source
Trading.value_at_riskFunction
value_at_risk(t::Trader, period::Function=day; cutoff = 0.05)

Calculates the value at risk (VaR) of a Trader. Value at risk is a measure of the potential loss of an investment over a certain time horizon, and is defined as the maximum loss expected at a given confidence level.

cutoff: the confidence level at which to calculate value at risk. The confidence level represents the probability of the maximum loss being less than or equal to the value at risk. The default value is 0.05, representing a 5% confidence level.

source
Trading.maximum_drawdownFunction

Calculates the maximum drawdown of a Trader object. Maximum drawdown is a measure of the largest loss experienced by an investment over a certain time period, and is defined as the peak-to-trough decline in portfolio value.

source

Core Systems

Trading.FillerType

When the status of an Order changes to "filled", the filled quantity and average fill price is registered in a Filled Component.

source
Trading.DayCloserType
DayCloser([interval::Period = Minute(1)])

Closes the day. Will run during the time interval [market_close - interval, market_close]. Currently it just removes pending trades.

source

Reference

Trading.start_dataFunction
start_data(trader; interval = Minute(1))

Starts the trader.data_tasks. It opens a DataStream for each Asset Class, and registers the AssetLedgers to it, in order to receive bar updates.

interval: signifies the desired interval of bar updates. If a bar for a given asset arrives after more than interval, bars will be interpolated between the last and new bar so the time interval between adjacent bars is always interval.

source
Trading.start_mainFunction
start_main(trader::Trader; sleep_time = 1, kwargs...)

Starts the trader.main_task. This periodically executes the core systems of the Trader, with at least sleep_time between executions.

source