Reputation: 1453
I want to write a function, which represents a trading simulation. I have a dataframe of financial asset prices and I want to create a trading strategy, which is based on signals.
Here is my dataframe:
(open = opening price, close = closing price, return= rate of change in %)
date open close return signal
<date> <dbl> <dbl> <dbl> <dbl>
1 2015-01-20 213. 211. -1 0
2 2015-01-21 211. 227. 7 1
3 2015-01-22 227. 233. 3 0
4 2015-01-23 234. 233. 0 0
5 2015-01-24 233. 248. 7 1
6 2015-01-25 247. 254. 3 0
7 2015-01-26 254. 273. 8 1
8 2015-01-27 273. 263. -4 0
9 2015-01-28 263. 234. -11 0
10 2015-01-29 233. 234. 0 0
My trading strategy is described as follows: if there is a signal on day t
, then buy on the following day t+1
to the opening price and sell to the closing price. In my example dataset there is a signal on day 2, so I buy on day 3 and sell to the closing price of day 3. I invest 100$, so I have a gain on day 3 of 3$. The next signal comes on day 5, so I invest my 103$ on day 6 an I get 3 additional Dollar. This table illustrates my trading strategy:
date open close return signal trading.strategy capital
<date> <dbl> <dbl> <dbl> <dbl>
1 2015-01-20 213. 211. -1 0 - 100
2 2015-01-21 211. 227. 7 1 - 100
3 2015-01-22 227. 233. 3 0 buy+sell 103
4 2015-01-23 234. 233. 0 0 - 103
5 2015-01-24 233. 248. 7 1 - 103
6 2015-01-25 247. 254. 3 0 buy+sell 106
7 2015-01-26 254. 273. 8 1 - 106
8 2015-01-27 273. 263. -4 0 buy+sell 102
9 2015-01-28 263. 234. -11 0 - 102
10 2015-01-29 233. 234. 0 0 - 102
Can someone help me to write a function, that executes my trading strategy?
Here is my data:
structure(list(date = structure(c(16455, 16456, 16457, 16458,
16459, 16460, 16461, 16462, 16463, 16464), class = "Date"), open = c(212.91,
211.38, 227.32, 233.52, 232.7, 247.35, 254.08, 273.17, 263.35,
233.35), close = c(211.32, 226.9, 233.41, 232.88, 247.85, 253.72,
273.47, 263.48, 233.91, 233.51), return = c(-1, 7, 3, 0, 7, 3,
8, -4, -11, 0), signal = c(0, 1, 0, 0, 1, 0, 1, 0, 0, 0)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -10L))
Upvotes: 3
Views: 670
Reputation: 4520
Just developing @Lennyy strategy, please don't consider this as an independent solution:
library(tidyverse)
CPTL = 100
right_join(
filter(dat, lag(signal == 1)) %>%
mutate(
trading.strategy = 'buy+sell',
capital = CPTL + cumsum(return / 100) * CPTL
),
dat
) %>%
mutate(
capital = replace_na(fill(., capital)$capital, CPTL),
trading.strategy = replace_na(trading.strategy, '-')
)
# A tibble: 10 x 7
# date open close return signal trading.strategy capital
# <date> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
# 1 2015-01-20 213. 211. -1 0 - 100
# 2 2015-01-21 211. 227. 7 1 - 100
# 3 2015-01-22 227. 233. 3 0 buy+sell 103
# 4 2015-01-23 234. 233. 0 0 - 103
# 5 2015-01-24 233. 248. 7 1 - 103
# 6 2015-01-25 247. 254. 3 0 buy+sell 106
# 7 2015-01-26 254. 273. 8 1 - 106
# 8 2015-01-27 273. 263. -4 0 buy+sell 102
# 9 2015-01-28 263. 234. -11 0 - 102
#10 2015-01-29 233. 234. 0 0 - 102
Upvotes: 0
Reputation: 210
library(dplyr)
initial_capital <- 10000
df %>%
mutate(
trade = ifelse(lag(signal, default = 0), 1, 0),
trading.strategy = ifelse(trade, "buy+sell", "-"),
days_return = trade * (close - open) / (open),
cum_return = cumsum(days_return),
capital = initial_capital * (1 + cum_return)
) %>%
select(-trade,-return)
# A tibble: 10 x 8
date open close signal trading.strategy days_return cum_return capital
<date> <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl>
1 2015-01-20 213. 211. 0 - 0 0 10000
2 2015-01-21 211. 227. 1 - 0 0 10000
3 2015-01-22 227. 233. 0 buy+sell 0.0268 0.0268 10268.
4 2015-01-23 234. 233. 0 - 0 0.0268 10268.
5 2015-01-24 233. 248. 1 - 0 0.0268 10268.
6 2015-01-25 247. 254. 0 buy+sell 0.0258 0.0525 10525.
7 2015-01-26 254. 273. 1 - 0 0.0525 10525.
8 2015-01-27 273. 263. 0 buy+sell -0.0355 0.0171 10171.
9 2015-01-28 263. 234. 0 - 0 0.0171 10171.
10 2015-01-29 233. 234. 0 - 0 0.0171 10171.
Upvotes: 2
Reputation: 6132
You could do something like this:
library(tidyverse)
df %>%
mutate(trading.strategy = if_else(lag(signal) == 1, "buy+sell", "-")) %>%
filter(trading.strategy == "buy+sell") %>%
mutate(capital = 100 + cumsum(return)) %>%
right_join(df) %>%
fill(capital) %>%
mutate(capital = if_else(is.na(capital), 100, capital),
trading.strategy = if_else(is.na(trading.strategy), "-", trading.strategy))
date open close return signal trading.strategy capital
<date> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
1 2015-01-20 213. 211. -1 0 - 100
2 2015-01-21 211. 227. 7 1 - 100
3 2015-01-22 227. 233. 3 0 buy+sell 103
4 2015-01-23 234. 233. 0 0 - 103
5 2015-01-24 233. 248. 7 1 - 103
6 2015-01-25 247. 254. 3 0 buy+sell 106
7 2015-01-26 254. 273. 8 1 - 106
8 2015-01-27 273. 263. -4 0 buy+sell 102
9 2015-01-28 263. 234. -11 0 - 102
10 2015-01-29 233. 234. 0 0 - 102
Upvotes: 2