动量

MACD指标择时交易策略分析

引言

技术分析是金融市场中常用的分析方法,其中MACD指标是一种重要的趋势跟踪指标,能够反映价格波动的趋势和动量。本研究旨在通过R语言实现基于MACD指标的股票择时交易策略,并通过历史数据回测寻找最佳参数组合。

研究方法

数据获取与处理

我们将使用quantmod包获取股票数据,并使用quantstrat包进行策略回测。首先加载所需的包:

# 加载必要的包
library(quantmod)
library(quantstrat)
library(eTTR)
library(PerformanceAnalytics)
library(ggplot2)
library(dplyr)
library(tibble)
library(scales)
library(gridExtra)
library(showtext)
font_add("SimHei", regular = "SimHei.ttf")
showtext_auto()

接下来,我们获取TSLA的历史数据作为研究对象:

# 设置获取数据的起始和结束日期
startdate.st <- as.Date("2018-01-01")
enddate.st <- as.Date("2023-06-01")

# 获取上证指数数据
getSymbols("TSLA", 
           src = "yahoo", 
           from = startdate.st, 
           to = enddate.st)
## [1] "TSLA"
colnames(TSLA) <- c("Open", "High", "Low", 
                    "Close", "Volume", "Adjusted")

# 查看数据结构
head(TSLA)
##                Open     High      Low    Close    Volume Adjusted
## 2018-01-02 20.80000 21.47400 20.73333 21.36867  65283000 21.36867
## 2018-01-03 21.40000 21.68333 21.03667 21.15000  67822500 21.15000
## 2018-01-04 20.85800 21.23667 20.37867 20.97467 149194500 20.97467
## 2018-01-05 21.10800 21.14933 20.80000 21.10533  68868000 21.10533
## 2018-01-08 21.06667 22.46800 21.03333 22.42733 147891000 22.42733
## 2018-01-09 22.34400 22.58667 21.82667 22.24600 107199000 22.24600
summary(TSLA)
##      Index                 Open             High             Low        
##  Min.   :2018-01-02   Min.   : 12.07   Min.   : 12.45   Min.   : 11.80  
##  1st Qu.:2019-05-10   1st Qu.: 21.42   1st Qu.: 21.82   1st Qu.: 21.04  
##  Median :2020-09-15   Median :126.48   Median :130.84   Median :122.50  
##  Mean   :2020-09-14   Mean   :135.13   Mean   :138.26   Mean   :131.71  
##  3rd Qu.:2022-01-20   3rd Qu.:230.08   3rd Qu.:235.64   3rd Qu.:224.40  
##  Max.   :2023-05-31   Max.   :411.47   Max.   :414.50   Max.   :405.67  
##      Close            Volume             Adjusted     
##  Min.   : 11.93   Min.   : 29401800   Min.   : 11.93  
##  1st Qu.: 21.50   1st Qu.: 77479900   1st Qu.: 21.50  
##  Median :125.58   Median :105881850   Median :125.58  
##  Mean   :135.07   Mean   :134180816   Mean   :135.07  
##  3rd Qu.:231.07   3rd Qu.:159549600   3rd Qu.:231.07  
##  Max.   :409.97   Max.   :914082000   Max.   :409.97

MACD指标计算原理

MACD指标由三条曲线组成:DIF线、DEA线和MACD柱状图。其计算基于以下步骤:

R软件与多股票波动性及相关性的可视化

前言

在量化投资建模过程之前,有时候,我们需要对多只股票的价格走势、收益率序列、波动率等进行分析。下面给出使用 R 语言比较多只股票价格走势的完整解决方案。方案涵盖数据获取、清洗、可视化及基础分析全流程:

数据获取

安装与加载工具包

# 安装必要包(首次运行需取消注释)
# install.packages(c("quantmod", 
#                    "tidyverse", 
#                    "ggplot2", 
#                    "zoo", 
#                    "corrplot"))

library(quantmod)   # 获取金融数据
library(tidyverse)  # 数据处理
library(ggplot2)    # 可视化
library(zoo)        # 时间序列处理

定义股票代码与时间范围

# 股票代码列表(支持多市场,如A股需加 .SS/.SZ)
# 苹果、谷歌、微软、英伟达
stocks <- c("AAPL", "GOOGL", "MSFT", "NVDA")  
# 时间范围
start_date <- "2023-01-01"
end_date <- Sys.Date()  # 获取当前日期

批量获取股票数据

# 获取数据
getSymbols(stocks, 
           src = "yahoo", 
           from = start_date, 
           to = end_date)
## [1] "AAPL"  "GOOGL" "MSFT"  "NVDA"
# 处理数据
stock_data <- lapply(stocks, function(x) {
  data <- as_tibble(get(x)) %>%
    mutate(Date = index(get(x))) %>%
    rename_with(~ gsub(paste0("^", x, "\\."), "", .x)) %>%
    select(Date, Close) %>%
    mutate(symbol = x) %>%  # 添加股票代码列
    rename(price = Close)   # 重命名收盘价列
}) %>%
  bind_rows()

# 查看结果
head(stock_data)
## # A tibble: 6 × 3
##   Date       price symbol
##   <date>     <dbl> <chr> 
## 1 2023-01-03  125. AAPL  
## 2 2023-01-04  126. AAPL  
## 3 2023-01-05  125. AAPL  
## 4 2023-01-06  130. AAPL  
## 5 2023-01-09  130. AAPL  
## 6 2023-01-10  131. AAPL

数据清洗

处理缺失值

library(dplyr)
# 检查缺失值
missing_values <- stock_data %>%
  group_by(symbol) %>%
  summarise(missing = sum(is.na(price)))

# 填充缺失值(使用前向填充)
stock_data <- stock_data %>%
  group_by(symbol) %>%
  mutate(price = na.locf(price))

对齐时间序列

library(dplyr)
# 生成完整日期序列
full_dates <- tibble(Date = seq(as.Date(start_date), 
                                as.Date(end_date), 
                                by = "day"))

# 左连接填充所有日期
stock_data <- full_dates %>%
  left_join(stock_data, by = "Date") %>%
  group_by(symbol) %>%
  fill(price, .direction = "downup") %>%
  na.omit()

价格走势可视化

基础折线图

library(dplyr)
ggplot(stock_data, aes(x = Date, y = price, color = symbol)) +
  geom_line(linewidth = 0.8) +
  labs(title = "多只股票价格走势对比",
       x = "日期",
       y = "收盘价",
       color = "股票代码") +
  theme_minimal() +
  theme(legend.position = "top") +  
  scale_color_manual(values = c("AAPL" = "red", 
                                "GOOGL" = "blue", 
                                "MSFT" = "green", 
                                "NVDA" = "purple")
                     )

对数收益率对比

library(dplyr)
# 计算对数收益率
return_data <- stock_data %>%
  group_by(symbol) %>%
  mutate(log_return = log(price) - log(lag(price))) %>%
  na.omit()

# 绘制收益率曲线
ggplot(return_data, 
       aes(x = Date, y = log_return, color = symbol)) +
  geom_line(alpha = 0.7) +
  labs(title = "对数收益率对比",
       x = "日期",
       y = "对数收益率",
       color = "股票代码") +
  theme_minimal() + 
  theme(legend.position = "top") # 图例放底部

绘制对数收益率密度图:

基于动量轮动策略的有效性分析

引言

动量效应是金融市场中一种重要的现象,指过去表现较好的资产在未来短期内往往继续表现 较好,而过去表现较差的资产则继续表现较差。基于动量效应的交易策略已经被广泛研究和 应用。

在股票市场中,大盘股和小盘股通常具有不同的风险收益特征和市场表现。本研究旨在探索 一种基于动量的轮动策略,通过比较大盘股和小盘股的相对强度,动态调整投资组合的配置, 以获取超额收益。

我们将使用R语言实现这一策略,并通过历史数据验证其有效性。同时,我们会优化策略参数, 测试参数敏感性,并在样本外数据上验证策略的稳健性。

数据准备与分析

首先加载必要的R包并获取股票数据。我们将选取多只大盘股和小盘股作为研究对象。

# 加载必要的R包
library(quantmod)
library(PerformanceAnalytics)
library(foreach)
library(doParallel)
library(ggplot2)
library(dplyr)
library(tidyr)
library(caret)
library(magrittr)

接下来,我们获取股票数据。我们将选择10只大盘股和10只小盘股作为样本。大盘股选取标 普500指数成分股中市值最大的10只,小盘股选取罗素2000指数成分股中市值最小的10只。

# 设置起止日期
start_date <- "2018-01-01"
end_date <- "2023-01-01"
out_of_sample_date <- "2023-01-02"
end_oos_date <- "2023-12-31"

# 大盘股列表
large_cap_symbols <- c("AAPL", "MSFT", "AMZN", "TSLA")

# 小盘股列表
small_cap_symbols <- c("ARQT", "AVXL", "BPMC", "CELZ")

# 所有股票代码
all_symbols <- c(large_cap_symbols, small_cap_symbols)

# 获取股票数据
stock_data <- list()
for (symbol in all_symbols) {
  tryCatch(
    {
      stock_data_raw <- getSymbols(symbol, 
                                   from = start_date, 
                                   to = end_date, 
                                   auto.assign = FALSE)
      colnames(stock_data_raw) <- c("Open", 
                                    "High", 
                                    "Low", 
                                    "Close", 
                                    "Volume", 
                                    "Adjusted")
      stock_data[[symbol]] <- stock_data_raw
      cat("Successfully downloaded", symbol, "\n")
    },
    error = function(e) {
      cat("Error downloading", symbol, ":", conditionMessage(e), "\n")
    }
  )
}
## Successfully downloaded AAPL 
## Successfully downloaded MSFT 
## Successfully downloaded AMZN 
## Successfully downloaded TSLA 
## Successfully downloaded ARQT 
## Successfully downloaded AVXL 
## Successfully downloaded BPMC 
## Successfully downloaded CELZ
# 过滤掉下载失败的股票
valid_symbols <- names(stock_data)
large_cap_symbols <- large_cap_symbols[large_cap_symbols %in% valid_symbols]
small_cap_symbols <- small_cap_symbols[small_cap_symbols %in% valid_symbols]

# 获取样本外数据
oos_data <- list()
for (symbol in valid_symbols) {
  tryCatch(
    {
      oss_data_raw <- getSymbols(symbol, 
                                 from = out_of_sample_date, 
                                 to = end_oos_date, 
                                 auto.assign = FALSE)
      colnames(oss_data_raw) <- c("Open", 
                                  "High", 
                                  "Low", 
                                  "Close", 
                                  "Volume", 
                                  "Adjusted")
      oos_data[[symbol]] <- oss_data_raw
      cat("Successfully downloaded OOS data for", symbol, "\n")
    },
    error = function(e) {
      cat("Error downloading OOS data for", symbol, ":", conditionMessage(e), "\n")
    }
  )
}
## Successfully downloaded OOS data for AAPL 
## Successfully downloaded OOS data for MSFT 
## Successfully downloaded OOS data for AMZN 
## Successfully downloaded OOS data for TSLA 
## Successfully downloaded OOS data for ARQT 
## Successfully downloaded OOS data for AVXL 
## Successfully downloaded OOS data for BPMC 
## Successfully downloaded OOS data for CELZ

让我们计算并可视化大盘股和小盘股的平均价格走势,以便对数据有一个直观的了解。