xuebaunion@vip.163.com

3551 Trousdale Rkwy, University Park, Los Angeles, CA

留学生论文指导和课程辅导

无忧GPA：https://www.essaygpa.com

工作时间：全年无休-早上8点到凌晨3点

扫码添加客服微信

扫描添加客服微信

r代写-COMP226-assignment 2

时间：2021-04-27

COMP226: Intro to backtester_v5.5

This document gives an introduction to the backtester_v5.5 framework, which is used in

assignment 2. As a first step, download backtester_v5.5.zip from Canvas and unzip it:

backtester_v5.5

├── DATA

│ ├── A2

│ │ ├── 01.csv

│ │ ├── 02.csv

│ │ ├── 03.csv

│ │ ├── 04.csv

│ │ ├── 05.csv

│ │ ├── 06.csv

│ │ ├── 07.csv

│ │ ├── 08.csv

│ │ ├── 09.csv

│ │ └── 10.csv

│ └── EXAMPLE

│ ├── 01.csv

│ ├── 02.csv

│ ├── 03.csv

│ ├── 04.csv

│ └── 05.csv

├── a2_main_template.R

├── a2_periods.R

├── a2_test_getTMA.R

├── a2_yamls

│ ├── x1xxx

│ │ └── results.yaml

│ ├── x1yyy

│ │ └── results.yaml

│ └── x1zzz

│ └── results.yaml

├── example_strategies.R

├── framework

│ ├── backtester.R

│ ├── data.R

│ └── processResults.R

├── main.R

└── strategies

├── a2_strategy_template.R

├── bbands_contrarian.R

├── bbands_holding_period.R

├── bbands_trend_following.R

├── copycat.R

├── fixed.R

└── rsi_contrarian.R

9 directories, 33 files

Next, open R and make sure that the working directory is the backtester_v5.5 directory

you just created (use setwd if required). Now try the example code as follows:

source('main.R')

If this doesn't work, first make sure you are have set the working directory correctly, and

then make sure you have installed all the required packages (see any error messages to see

what the problem is). When it works it will produce a plot like the following, with one equity

curve for each series (5 in this case), and one aggregate equity curve (at the top):

Active on 100 % of days; PD ratio = −153.44

Jan Apr Jul

999400

999600

999800

1000000

05 : PD ratio = 3.88 / 13.7 = 0.28

03 : PD ratio = −0.19 04 : PD ratio = 23.02 / 138 = 0.17

01 : PD ratio = 0.06 / 0.03 = 1.97 02 : PD ratio = −180.2

Jan Apr Jul

Jan Apr Jul Jan Apr Jul

Jan Apr Jul Jan Apr Jul

−600

−400

−200

0

−50

0

50

100

0.00

0.02

0.04

0.06

−0.5

−0.4

−0.3

−0.2

−0.1

0.0

−5

0

5

Let's go through main.R and see what the individual parts do.

Sourcing the framework and example strategies. First we source the framework itself.

source('framework/data.R')

source('framework/backtester.R')

source('framework/processResults.R')

Then we source example_strategies.R, which gives an easy way to run several examples.

source('example_strategies.R')

Loading data. Next, we load in data using getData, which is defined in framework/data.R.

This function returns a list of xts objects, which will be passed to the function backtester.

dataList <- getData(directory="EXAMPLE")

There are 5 series in backtester_5.5/DATA/EXAMPLE/, and therefore dataList has 5

elements. Every element is an xts with All the series have the same start and end dates:

> for (x in dataList) print(paste(class(x)[1],start(x),end(x)))

[1] "xts 1970-01-02 1970-07-20"

[1] "xts 1970-01-02 1970-07-20"

[1] "xts 1970-01-02 1970-07-20"

[1] "xts 1970-01-02 1970-07-20"

[1] "xts 1970-01-02 1970-07-20"

The individual series contain Open, High, Low, Close, and Volume columns:

> head(dataList[[1]])

Open High Low Close Volume

1970-01-02 0.7676 0.7698 0.7667 0.7691 3171

1970-01-03 0.7689 0.7737 0.7683 0.7729 6311

1970-01-04 0.7725 0.7748 0.7718 0.7732 4317

1970-01-05 0.7739 0.7756 0.7739 0.7751 3409

1970-01-06 0.7760 0.7770 0.7754 0.7757 2904

1970-01-07 0.7738 0.7744 0.7728 0.7743 3514

Subsetting the data. Next we choose to only use the first 200 days:

# subset data: just use first 200 days

dataList <- lapply(dataList, function(x) x[1:200])

Loading a strategy. We pick a strategy from the list in example_strategies.R:

example_strategies <- c("fixed",

"copycat",

"rsi_contrarian",

"bbands_trend_following",

"bbands_contrarian",

"bbands_holding_period")

Returning to main.R, we see where we picked one (and then checked the choice is valid):

# choose strategy from example_strategies

strategy <- "fixed"

# check that the choice is valid

stopifnot(is_valid_example_strategy(strategy))

Now we load the strategy and its parameters as defined in example_strategies.R:

load_strategy(strategy) # function from example_strategies.R

The structure of a strategy. The code strategies/fixed.R, which we just loaded, is:

# In period 1, market orders are used to take positions according to params$size

# No further orders are placed by getOrders

# The backtester automatically exits all positions when the data runs out

getOrders <- function(store, newRowList, currentPos, info, params) {

allzero <- rep(0,length(newRowList))

marketOrders <- allzero

if (is.null(store)) {

marketOrders <- params$sizes

store <- 1 # not null

}

return(list(store=store,marketOrders=marketOrders,

limitOrders1=allzero,

limitPrices1=allzero,

limitOrders2=allzero,

limitPrices2=allzero))

}

The backtester runs a strategy by calling getOrders, which always has the same arguments:

getOrders <- function(store, newRowList, currentPos, info, params) {

• store: contains all data you choose to save from one period to the next

• newRowList: new day's data (a list of single rows from the series)

• currentPos: the vector of current positions in each series

• params: a list of parameters that are sent to the function

In fixed.R, getOrders is the only function. Here's how strategy fixed.R works. In period 1,

the backtester always passes store to getOrders with NULL as its value. Thus in period 1

(and only in period 1) marketOrders will be set as params$sizes. In example_strategies.R

we see params$sizes set as 1 for all series, i.e., we buy and hold one unit in every series:

list(sizes=rep(1,5))

Changing the parameters. We can change params to stay flat in some series and go short

in others, e.g., with the following in example_strategies.R or main.R:

params <- list(sizes=c(1,2,0,0,-1))

Active on 100 % of days; PD ratio = −364.37

Jan Apr Jul

998500

999000

999500

1000000

05 : PD ratio = −4.02

03 : PD ratio = 0 04 : PD ratio = 0

01 : PD ratio = 0.06 / 0.03 = 1.97 02 : PD ratio = −360.4

Jan Apr Jul

Jan Apr Jul Jan Apr Jul

Jan Apr Jul Jan Apr Jul

−1500

−1000

−500

0

−0.050

−0.025

0.000

0.025

0.050

0.00

0.02

0.04

0.06

−0.050

−0.025

0.000

0.025

0.050

−5

0

5

Compare the new and old equity curves: For series 1 they are the same, for series 2 the

new one is scaled by 2, for series 3 and 4 we now don't trade, and for series 5 the equity

curve is reflected in the profit and loss axis.

Market orders. fixed.R uses market orders. The backester framework also supports limit

orders, but we will not use them for assignment 2.

In the framework, trading decisions are made after the close of day k, with trades executed

on day k+1. Per day, the framework supports one market order for each series, and

two limit orders for each series. These orders are returned from getOrders as follows:

return(list(store=store,marketOrders=marketOrders,

limitOrders1=limitOrders1,

limitPrices1=limitPrices1,

limitOrders2=limitOrders2,

limitPrices2=limitPrices2))

Market orders will be executed at the open on day k+1. The sizes and directions are

encoded in the element marketOrders of the list returned by getOrders. For example

c(0,-5,0,1,0)

means place a market order for 5 units short in series 2, and 1 unit long in series 4.

Since we will not use limit orders for assignment 2, so you can leave limitOrders1,

limitPrices1, limitOrders2, limitPrices2 as zero vectors when you do assignment 2.

Running the backtest. Finally we do the backtest and plot the results:

# Do backtest

results <- backtest(dataList,getOrders,params,sMult=0.2)

pfolioPnL <- plotResults(dataList,results)

The arguments to the function backtest are the following:

• dataList - list of (daily) xts objects (with identical indexes)

• getOrders - the strategy

• params - the parameters for the strategy

• sMult - slippage multiplier (proportion of overnight gap)

Results for individual series are in results$pnlList. plotResults produces he plots above,

and returns pfolioPnL, which has a named element fitAgg (short for "aggregate fitness"):

> print(pfolioPnL$fitAgg)

[1] -153.44

fitAgg is defined as the Profit Drawdown Ratio (PD ratio). It is a profit/loss (as opposed

to return) version of the Calmar ratio, namely, it is the final profit divided by the profit/loss

maximum drawdown if the strategy makes a profit, or, if the strategy makes a loss, it is just

that loss (which is negative). Notice that pfolioPnL$fitAgg matches up with the "PD ratio"

shown in equity curve produced by plotResults.

In the final part of assignment 2, you are asked to parameter optimize for "fitAgg". For that

you can use params argument to getOrders.

学霸联盟

This document gives an introduction to the backtester_v5.5 framework, which is used in

assignment 2. As a first step, download backtester_v5.5.zip from Canvas and unzip it:

backtester_v5.5

├── DATA

│ ├── A2

│ │ ├── 01.csv

│ │ ├── 02.csv

│ │ ├── 03.csv

│ │ ├── 04.csv

│ │ ├── 05.csv

│ │ ├── 06.csv

│ │ ├── 07.csv

│ │ ├── 08.csv

│ │ ├── 09.csv

│ │ └── 10.csv

│ └── EXAMPLE

│ ├── 01.csv

│ ├── 02.csv

│ ├── 03.csv

│ ├── 04.csv

│ └── 05.csv

├── a2_main_template.R

├── a2_periods.R

├── a2_test_getTMA.R

├── a2_yamls

│ ├── x1xxx

│ │ └── results.yaml

│ ├── x1yyy

│ │ └── results.yaml

│ └── x1zzz

│ └── results.yaml

├── example_strategies.R

├── framework

│ ├── backtester.R

│ ├── data.R

│ └── processResults.R

├── main.R

└── strategies

├── a2_strategy_template.R

├── bbands_contrarian.R

├── bbands_holding_period.R

├── bbands_trend_following.R

├── copycat.R

├── fixed.R

└── rsi_contrarian.R

9 directories, 33 files

Next, open R and make sure that the working directory is the backtester_v5.5 directory

you just created (use setwd if required). Now try the example code as follows:

source('main.R')

If this doesn't work, first make sure you are have set the working directory correctly, and

then make sure you have installed all the required packages (see any error messages to see

what the problem is). When it works it will produce a plot like the following, with one equity

curve for each series (5 in this case), and one aggregate equity curve (at the top):

Active on 100 % of days; PD ratio = −153.44

Jan Apr Jul

999400

999600

999800

1000000

05 : PD ratio = 3.88 / 13.7 = 0.28

03 : PD ratio = −0.19 04 : PD ratio = 23.02 / 138 = 0.17

01 : PD ratio = 0.06 / 0.03 = 1.97 02 : PD ratio = −180.2

Jan Apr Jul

Jan Apr Jul Jan Apr Jul

Jan Apr Jul Jan Apr Jul

−600

−400

−200

0

−50

0

50

100

0.00

0.02

0.04

0.06

−0.5

−0.4

−0.3

−0.2

−0.1

0.0

−5

0

5

Let's go through main.R and see what the individual parts do.

Sourcing the framework and example strategies. First we source the framework itself.

source('framework/data.R')

source('framework/backtester.R')

source('framework/processResults.R')

Then we source example_strategies.R, which gives an easy way to run several examples.

source('example_strategies.R')

Loading data. Next, we load in data using getData, which is defined in framework/data.R.

This function returns a list of xts objects, which will be passed to the function backtester.

dataList <- getData(directory="EXAMPLE")

There are 5 series in backtester_5.5/DATA/EXAMPLE/, and therefore dataList has 5

elements. Every element is an xts with All the series have the same start and end dates:

> for (x in dataList) print(paste(class(x)[1],start(x),end(x)))

[1] "xts 1970-01-02 1970-07-20"

[1] "xts 1970-01-02 1970-07-20"

[1] "xts 1970-01-02 1970-07-20"

[1] "xts 1970-01-02 1970-07-20"

[1] "xts 1970-01-02 1970-07-20"

The individual series contain Open, High, Low, Close, and Volume columns:

> head(dataList[[1]])

Open High Low Close Volume

1970-01-02 0.7676 0.7698 0.7667 0.7691 3171

1970-01-03 0.7689 0.7737 0.7683 0.7729 6311

1970-01-04 0.7725 0.7748 0.7718 0.7732 4317

1970-01-05 0.7739 0.7756 0.7739 0.7751 3409

1970-01-06 0.7760 0.7770 0.7754 0.7757 2904

1970-01-07 0.7738 0.7744 0.7728 0.7743 3514

Subsetting the data. Next we choose to only use the first 200 days:

# subset data: just use first 200 days

dataList <- lapply(dataList, function(x) x[1:200])

Loading a strategy. We pick a strategy from the list in example_strategies.R:

example_strategies <- c("fixed",

"copycat",

"rsi_contrarian",

"bbands_trend_following",

"bbands_contrarian",

"bbands_holding_period")

Returning to main.R, we see where we picked one (and then checked the choice is valid):

# choose strategy from example_strategies

strategy <- "fixed"

# check that the choice is valid

stopifnot(is_valid_example_strategy(strategy))

Now we load the strategy and its parameters as defined in example_strategies.R:

load_strategy(strategy) # function from example_strategies.R

The structure of a strategy. The code strategies/fixed.R, which we just loaded, is:

# In period 1, market orders are used to take positions according to params$size

# No further orders are placed by getOrders

# The backtester automatically exits all positions when the data runs out

getOrders <- function(store, newRowList, currentPos, info, params) {

allzero <- rep(0,length(newRowList))

marketOrders <- allzero

if (is.null(store)) {

marketOrders <- params$sizes

store <- 1 # not null

}

return(list(store=store,marketOrders=marketOrders,

limitOrders1=allzero,

limitPrices1=allzero,

limitOrders2=allzero,

limitPrices2=allzero))

}

The backtester runs a strategy by calling getOrders, which always has the same arguments:

getOrders <- function(store, newRowList, currentPos, info, params) {

• store: contains all data you choose to save from one period to the next

• newRowList: new day's data (a list of single rows from the series)

• currentPos: the vector of current positions in each series

• params: a list of parameters that are sent to the function

In fixed.R, getOrders is the only function. Here's how strategy fixed.R works. In period 1,

the backtester always passes store to getOrders with NULL as its value. Thus in period 1

(and only in period 1) marketOrders will be set as params$sizes. In example_strategies.R

we see params$sizes set as 1 for all series, i.e., we buy and hold one unit in every series:

list(sizes=rep(1,5))

Changing the parameters. We can change params to stay flat in some series and go short

in others, e.g., with the following in example_strategies.R or main.R:

params <- list(sizes=c(1,2,0,0,-1))

Active on 100 % of days; PD ratio = −364.37

Jan Apr Jul

998500

999000

999500

1000000

05 : PD ratio = −4.02

03 : PD ratio = 0 04 : PD ratio = 0

01 : PD ratio = 0.06 / 0.03 = 1.97 02 : PD ratio = −360.4

Jan Apr Jul

Jan Apr Jul Jan Apr Jul

Jan Apr Jul Jan Apr Jul

−1500

−1000

−500

0

−0.050

−0.025

0.000

0.025

0.050

0.00

0.02

0.04

0.06

−0.050

−0.025

0.000

0.025

0.050

−5

0

5

Compare the new and old equity curves: For series 1 they are the same, for series 2 the

new one is scaled by 2, for series 3 and 4 we now don't trade, and for series 5 the equity

curve is reflected in the profit and loss axis.

Market orders. fixed.R uses market orders. The backester framework also supports limit

orders, but we will not use them for assignment 2.

In the framework, trading decisions are made after the close of day k, with trades executed

on day k+1. Per day, the framework supports one market order for each series, and

two limit orders for each series. These orders are returned from getOrders as follows:

return(list(store=store,marketOrders=marketOrders,

limitOrders1=limitOrders1,

limitPrices1=limitPrices1,

limitOrders2=limitOrders2,

limitPrices2=limitPrices2))

Market orders will be executed at the open on day k+1. The sizes and directions are

encoded in the element marketOrders of the list returned by getOrders. For example

c(0,-5,0,1,0)

means place a market order for 5 units short in series 2, and 1 unit long in series 4.

Since we will not use limit orders for assignment 2, so you can leave limitOrders1,

limitPrices1, limitOrders2, limitPrices2 as zero vectors when you do assignment 2.

Running the backtest. Finally we do the backtest and plot the results:

# Do backtest

results <- backtest(dataList,getOrders,params,sMult=0.2)

pfolioPnL <- plotResults(dataList,results)

The arguments to the function backtest are the following:

• dataList - list of (daily) xts objects (with identical indexes)

• getOrders - the strategy

• params - the parameters for the strategy

• sMult - slippage multiplier (proportion of overnight gap)

Results for individual series are in results$pnlList. plotResults produces he plots above,

and returns pfolioPnL, which has a named element fitAgg (short for "aggregate fitness"):

> print(pfolioPnL$fitAgg)

[1] -153.44

fitAgg is defined as the Profit Drawdown Ratio (PD ratio). It is a profit/loss (as opposed

to return) version of the Calmar ratio, namely, it is the final profit divided by the profit/loss

maximum drawdown if the strategy makes a profit, or, if the strategy makes a loss, it is just

that loss (which is negative). Notice that pfolioPnL$fitAgg matches up with the "PD ratio"

shown in equity curve produced by plotResults.

In the final part of assignment 2, you are asked to parameter optimize for "fitAgg". For that

you can use params argument to getOrders.

学霸联盟