Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
An R interface to zipline.

Hello Quantopian community!

My name is Davis Vaughan. I am an enthusiastic R package developer, and have worked on projects such as tidyquant, tibbletime, and furrr.

Recently, I have been learning as much as I can about Quantopian, in particular the open source zipline python library. With new advancements in the R community such as reticulate, I had the insight that it might be possible to run zipline from R, using R code to write the initialize() and handle_data() functions (essentially freeing you to use any R package or function in your backtests and models).

I was right.

Below, you'll find a link to a highly in-development R package I'm calling flyingfox. It is an R interface to zipline, and if you scroll down to the example, I think you will like what you see!

https://github.com/DavisVaughan/flyingfox

I am working towards complete support for the exposed zipline API, but would love to hear your thoughts on the initial idea. If you have zipline installed locally, along with the quandl data bundle, you should be able to run the code yourself if you use R regularly and want to try it out. Documentation is still sparse, and I'm still working on getting installation details right for all platforms, but I've successfully installed and run the algo on Mac/Linux/Windows. I'm hoping this thread might be a place for me to ask questions if I run into any issues along the way!

For reference, here is what the classic dual moving average crossover example looks like in R code:

library(flyingfox)

fly_initialize <- function(context) {

  # We want to track what day we are on. The mean reversion algo we use  
  # should have at least 300 days of data before doing anything  
  context$i = 0L

  # We want to trade apple stock  
  context$asset = fly_symbol("AAPL")  
}

fly_handle_data <- function(context, data) {

  # Increment day  
  context$i <- context$i + 1L

  # While < 300 days of data, return  
  if(context$i < 300L) {  
    return()  
  }

  # Calculate a short term (100 day) moving average  
  # by pulling history for the asset (apple) and taking an average  
  short_hist <- fly_data_history(data, context$asset, "price", bar_count = 100L, frequency = "1d")  
  short_mavg <- mean(short_hist)

  # Calculate a long term (300 day) moving average  
  long_hist <- fly_data_history(data, context$asset, "price", bar_count = 300L, frequency = "1d")  
  long_mavg <- mean(long_hist)

  # If short > long, go 100% in apple  
  if(short_mavg > long_mavg) {  
    fly_order_target_percent(asset = context$asset, target = 1)  
  }  
  # Else if we hit the crossover, dump all of apple  
  else if (short_mavg < long_mavg) {  
    fly_order_target_percent(asset = context$asset, target = 0)  
  }

  # Record today's data  
  # We record the current apple price, along with the value of the short and long  
  # term moving average  
  fly_record(  
    AAPL = fly_data_current(data, context$asset, "price"),  
    short_mavg = short_mavg,  
    long_mavg = long_mavg  
  )

}

performance <- fly_run_algorithm(  
  initialize  = fly_initialize,  
  handle_data = fly_handle_data,  
  start       = as.Date("2013-01-01"),  
  end         = as.Date("2016-01-01")  
)

tail(performance)  
#> # A tibble: 6 x 41  
#>   date      AAPL algo_volatility algorithm_period… alpha benchmark_period…  
#>   <chr>    <dbl>           <dbl>             <dbl> <dbl>             <dbl>  
#> 1 2015-12…  109.           0.181             0.550 0.161          -0.0121  
#> 2 2015-12…  108.           0.181             0.550 0.161          -0.0137  
#> 3 2015-12…  107.           0.181             0.550 0.161          -0.0159  
#> 4 2015-12…  109.           0.181             0.550 0.159          -0.00545  
#> 5 2015-12…  107.           0.181             0.550 0.160          -0.0125  
#> 6 2015-12…  105.           0.181             0.550 0.162          -0.0224  
#> # ... with 35 more variables: benchmark_volatility <dbl>, beta <dbl>,  
#> #   capital_used <dbl>, ending_cash <dbl>, ending_exposure <dbl>,  
#> #   ending_value <dbl>, excess_return <dbl>, gross_leverage <dbl>,  
#> #   long_exposure <dbl>, long_mavg <dbl>, long_value <dbl>,  
#> #   longs_count <dbl>, max_drawdown <dbl>, max_leverage <dbl>,  
#> #   net_leverage <dbl>, orders <list>, period_close <dttm>,  
#> #   period_label <chr>, period_open <dttm>, pnl <dbl>,  
#> #   portfolio_value <dbl>, positions <list>, returns <dbl>, sharpe <dbl>,  
#> #   short_exposure <dbl>, short_mavg <dbl>, short_value <dbl>,  
#> #   shorts_count <dbl>, sortino <dbl>, starting_cash <dbl>,  
#> #   starting_exposure <dbl>, starting_value <dbl>, trading_days <dbl>,  
#> #   transactions <list>, treasury_period_return <dbl>  
2 responses

We have released a blog post that goes over flyingfox along with a few examples of running grid search optimization backtests in parallel in R.

http://www.business-science.io/business-science-labs/2018/05/31/backtesting-quantopian-zipline-tibbletime-furrr-flyingfox.html

There is also a free playground for flyingfox on RStudio Cloud. Create a free account and try out the examples there!

https://rstudio.cloud/project/38291

Thanks for sharing, tidyquant, tibbletime and furrr is very useful for quantitative data handling... Just install flyingfox on Windows but failed... Unable install zipline due to no Microsoft Visual Studio C++