strand
provides a framework for performing discrete
(share-level) simulations of investment strategies. Simulated portfolios
optimize exposure to an input signal subject to constraints such as
position size and factor exposure.
The package
vignette provides an in-depth discussion of setup and usage. See
vignette("strand")
.
The package’s sample data set includes value and size factors, as well as daily pricing information, for most of the stocks in the S&P 500 for the period June-August 2020. The source of fundamental data is EDGAR, and all pricing data was downloaded using the Tiingo Stock API. Special thanks to Tiingo for giving permission to release this data.
# Install the latest version from CRAN:
install.packages("strand")
# Install development version from GitHub using remotes:
install.packages("remotes")
::install_github("strand-tech/strand") remotes
The strand
package uses GLPK as the default solver
for portfolio optimization. As a result, it depends on package
Rglpk
.
It is possible to use SYMPHONY instead, by
setting solver: symphony
in the simulation’s configuration
file and installing the Rsymphony
package. Note that you
will need to install SYMPHONY on your system first, and on
OS X perform a few extra steps to install
Rsymphony
.
Four ingredients are required to run a simulation using
strand
:
Configuration file. A file in yaml format that describes the parameters of the simulation, such as the input signal, risk constraints, trading limits, position limits, the location of data inputs, etc.
Security reference. A listing of all securities allowed in the simulation and any categorical values (such as sector and industry) that can be used in exposure constraints.
Signal, factor, and supplementary data. Data for each day including the input signal (to which exposure is maximized) and any factors that appear in constraints. Supplementary data could include, for example, a daily measure of market capitalization for use in universe construction.
Pricing data. Daily prices, dividends, and trading volume for computing market values and filling orders. Unadjusted prices and accompanying adjustment ratios may be used.
library(strand)
# Load up sample data
data(sample_secref)
data(sample_pricing)
data(sample_inputs)
# Load sample configuration file
<- example_strategy_config()
config
# Create the Simulation object and run
<- Simulation$new(config,
sim raw_input_data = sample_inputs,
raw_pricing_data = sample_pricing,
security_reference_data = sample_secref)
$run()
sim
# Print overall statistics
$overallStatsDf() sim
## Item Gross Net
## 1 Total P&L -32,355 -40,867
## 2 Total Return on GMV (%) -1.8 -2.3
## 3 Annualized Return on GMV (%) -6.9 -8.7
## 4 Annualized Vol (%) 8.9 8.8
## 5 Annualized Sharpe -0.77 -0.98
## 6 Max Drawdown (%) -6.6 -6.8
## 7 Avg GMV 1,976,540
## 8 Avg NMV -716
## 9 Avg Count 189
## 10 Avg Daily Turnover 53,022
## 11 Holding Period (months) 3.6
To run an example shiny application that allows interactively configuring and running a simulation:
library(strand)
example_shiny_app()
If you have docker
and docker-compose
installed, you can run the example shiny application by cloning the github repository and
running the following commands from the top-level directory:
$ docker-compose build
$ docker-compose up
The application will run by default on port 80. To configure edit
docker-compose.yml
.