3
votes

R créer une simulation de trading

Je veux écrire une fonction, qui représente une simulation de trading. J'ai une base de données des prix des actifs financiers et je souhaite créer une stratégie de trading basée sur des signaux.

Voici ma base de données:

(open = cours d'ouverture, fermeture = cours de clôture, rendement = taux de variation en%)

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

Ma stratégie de trading est décrite comme suit: s'il y a un signal le jour t , alors acheter le suivant le jour t + 1 au cours d'ouverture et vendre au cours de clôture. Dans mon exemple de jeu de données, il y a un signal le jour 2, donc j'achète le jour 3 et je vends au cours de clôture du jour 3. J'investis 100 $, donc j'ai un gain au jour 3 de 3 $. Le signal suivant arrive le jour 5, donc j'investis mes 103 $ le jour 6 et j'obtiens 3 dollars supplémentaires. Ce tableau illustre ma stratégie de trading:

   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

Quelqu'un peut-il m'aider à écrire une fonction, qui exécute ma stratégie de trading?

Voici mes données:

    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


6 commentaires

BTW, dans ma réponse, j'ai supposé que majuscule devrait être 102 dans ligne 8 , puisque signal était 1 à la ligne 7 et return était -4 à la ligne 8 .


De plus, est-ce que return est donné ou cette colonne doit-elle être générée en fonction des variables open et close ?


@Lennyy oui vous avez raison. J'ai changé ce numéro.


@ Lennyy la colonne de retour est calculée sur les variables open et close : return = (open-close) / open


@Lennyy avez-vous des idées sur la façon dont je peux considérer les coûts de transaction? Par exemple, chaque transaction entraîne des coûts de 2%.


@ Tobkel: pensez à poser une nouvelle question à ce sujet


3 Réponses :


2
votes

Vous pouvez faire quelque chose comme ceci:

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


2 commentaires

@Lennyy. Notez que cela ne donnera un résultat correct que lorsque le capital initial est de 100 et est incorrect sinon, voir les modifications que j'ai apportées à ma réponse


@Lennyy, dans le dernier mutation , vous pouvez utiliser par exemple capital = replace_na (capital, 100) , la même chose pourrait être appliquée à la trading.strategy .



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


0 commentaires

0
votes

Je ne fais que développer la stratégie @Lennyy, veuillez ne pas considérer cela comme une solution indépendante:

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


0 commentaires