R 创建交易模拟

R create trading simulation

我想写一个函数,代表一个交易模拟。我有一个金融资产价格数据框,我想创建一个基于信号的交易策略。

这是我的数据框:

(open = 开盘价, close = 收盘价, return= 变化率 %)

    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

我的交易策略是这样描述的:如果day t上有信号,那么在下面的day t+1上买入到开盘价,卖出到收盘价。在我的示例数据集中,第 2 天有一个信号,所以我在第 3 天买入并以第 3 天的收盘价卖出。我投资 100 美元,所以我在第 3 天获得了 3 美元的收益。下一个信号在第 5 天出现,所以我在第 6 天投资了 103 美元,我得到了额外的 3 美元。这 table 说明了我的交易策略:

   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

谁能帮我写一个函数来执行我的交易策略?

这是我的数据:

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))

你可以这样做:

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
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.

只是在开发@Lennyy 策略,请不要将其视为一个独立的解决方案:

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