经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » R语言 » 查看文章
R与金钱游戏:均线黄金交叉1
来源:cnblogs  作者:yukiwu  时间:2019/11/8 8:51:15  对本文有异议

双11临近的我发现自己真的很穷很穷很穷(重要的问题说三遍)……

贫穷催人上进。于是我就寻思着在空闲时间自己捣鼓一下钱生钱的游戏是怎么玩的,毕竟就算注定做韭菜也要做一根有知识有理想的韭菜。

第一个要玩的模型就是股票交易中的均线黄金交叉。

作为一个基础的韭菜一定听说过均线黄金交叉原则,也就是说当短期移动平均线向上突破长期移动平均线,表明趋势见涨,适合买入;相反地如果短期移动平均线向下突破长期移动平均线,表明趋势看跌,适合卖出。

那么这个韭菜们都知道的交易原则是不是真的能帮大家赚钱呢?下面我们以中国平安为例(其实选A股分析还是很尴尬,万一无论如何都不能赚钱呢……)就建模简单地验证一下。

Required Packages


  1. library(quantmod)
  2. library(ggplot2)
  3. library(scales)


Get Data


首先利用 quantmod 包下载股价数据。股票的代码可以在雅虎财经查到。

  1. stock_code <- "601318.SS"
  2. start <- as.Date("2018-01-01")
  3. end <- as.Date("2020-01-01")
  4. stock <- getSymbols(stock_code, from=start, auto.assign=FALSE)
  5. names(stock) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
  6. stock <- stock[paste(start, end, sep='/')]$Close


Calculate Moving Average


移动平均数通常可分为简单移动平均数 (SMA),加权移动平均数 (WMA) 和指数移动平均数 (EMA)。

通常我们会选用指数移动平均数。因为移动平均数在一定程度上都会落后于股价的实时趋势,而指数移动平均数在计算时越新的数据加权比重越大,能更快地反映股价的变化。

  1. ma <- function(data, mas=c(5, 20, 60)) {
  2. ma_data <- data
  3. for(m in mas) {
  4. ma_data <- merge(ma_data, EMA(data, m))
  5. }
  6. ma_data <- na.locf(ma_data, fromLast = TRUE)
  7. names(ma_data) <- c('Value', paste('MA', mas, sep=''))
  8. return(ma_data)
  9. }

我们可以将计算结果画成图形:
01

Get Trading Signals


以 5 日和 20 日均线为例,我们可以按照均线黄金交叉原则找到买卖交易点,即某一天的 5 日移动平均数大于 20 日移动平均数时为买入,反之某一天的 5 日移动平均数小于 20 日移动平均数时为卖出。

我们可以将数据分组。当 5 日均线大于 20 日均线时为 “buy”; 当 5 日均线小于 20 日均线时为 “sell”。 其中 “buy” 和 “sell” 是以不定数量间隔出现的,那么每一段中第一个 “buy” 出现的时候为买入, 第一个 “sell” 出现的时候为卖出。在模拟交易的时候为了方便计算利润,我们将买入设为第一次交易,卖出设为最后一次交易。

如果我们一直依照均线黄金交叉原则,那么从 2018-01-01 开始至今一共有 30 次交易 (买卖合计)。

  1. get_signals<- function(data, mas_1=5, mas_2=20) {
  2. if(mas_1 == 0)
  3. ma_name_1 <- "Value"
  4. else
  5. ma_name_1 <- paste('MA', mas_1, sep='')
  6. ma_name_2 <- paste('MA', mas_2, sep='')
  7. ma_data <- data[, c("Value", ma_name_1, ma_name_2)] #please calculate ma value before and get a dataframe like the section above
  8. down_data <- ma_data[which(ma_data[, c(ma_name_1)] > ma_data[, c(ma_name_2)]), c("Value")]
  9. up_data <- ma_data[which(ma_data[, c(ma_name_1)] < ma_data[, c(ma_name_2)]), c("Value")]
  10. result <- merge(down_data, up_data)
  11. names(result) <- c("buy", "sell")
  12. result <- fortify(result, melt=TRUE)
  13. result<- result[-which(is.na(result$Value)),]
  14. signals <- result[order(result$Index),]
  15. signals$Signal <- ifelse(signals$Series == "buy", 1, 0)
  16. signals$Signal <- c(ifelse(signals$Series[1] == "buy", 1, -1),diff(signals$Signal))
  17. signals <- signals[which(signals$Signal != 0),]
  18. #delete odd rows
  19. if(nrow(signals)%%2 == 1) {
  20. if(signals$Series[1] == "buy")
  21. signals <- signals[-c(nrow(signals)),]
  22. else
  23. signals <- signals[-c(1),]
  24. }
  25. if(signals$Series[1] == "sell") {
  26. signals <- signals[-c(nrow(signals)),]
  27. signals <- signals[-c(1),]
  28. }
  29. return (signals)
  30. }


Mock Trading


上面我们已经找出交易点,但其实我们找出这些可能的历史交易点目的就是为了知道如果严格按照这些交易点进行交易能不能赚钱呀?

下面我们可以模拟一下交易的过程:

假设我们有 10,000 本金,全仓进入,交易费率为 0.3%

  1. mock_trading <- function(signals, capital=10000, position=1, fee=0.003){
  2. amount <- 0
  3. cash <- capital * position
  4. ticks <- data.frame()
  5. for(ii in 1:nrow(signals)){
  6. row <- signals[ii,]
  7. if(row$Series == "buy") {
  8. amount <- floor((cash/(1+fee))/row$Value)
  9. cash <- cash - amount * row$Value - (amount * row$Value) * fee
  10. }
  11. if(row$Series == "sell") {
  12. cash <- cash + amount * row$Value - (amount * row$Value) * fee
  13. amount <- 0
  14. }
  15. row$cash <- cash
  16. row$amount <- amount
  17. row$asset<- cash + amount * row$Value
  18. row$fee <- (amount * row$Value) * fee
  19. ticks<-rbind(ticks, row)
  20. }
  21. ticks$diff <- c(0, diff(ticks$asset))
  22. rise <- ticks[c(which(ticks$diff > 0)-1, which(ticks$diff > 0)),]
  23. rise <- rise[order(rise$Index),]
  24. fall <- ticks[c(which(ticks$Series=="sell" & ticks$diff < 0)-1, which(ticks$Series=="sell" & ticks$diff < 0)),]
  25. fall <- rise[order(fall$Index),]
  26. return(list(
  27. ticks = ticks,
  28. rise = rise,
  29. fall = fall
  30. ))
  31. }

如果严格按照均线黄金交叉原则,那么经过2年的股海沉浮之后,最后我们的本金只有 7962.18,亏损 2037.82, 而赚钱的交易只有6次 (买卖合计)。
02

我们将资产和股价曲线画成图形对比可以看出我们在前期的交易中是亏损很多的。一方面是股价走势确实是跌跌不休 (经历了 2018 年的韭菜们都知道),那还有没有交易选择错误的原因呢?
03

我们将盈利和亏损的交易分别画出来,就可以看出亏损的交易多在股价尚未形成趋势还在震荡,如 2018-08,以及 2018-10-2018-11 期间。所以从数据上来看,均线黄金交叉原则只能对股价已形成趋势的股票起指导作用。
04

不过我们也可以乐观地认为,只要我们能够避开震荡期,那么均线黄金交叉原则还是能够帮助我们小小赚一笔的。可是今日不知明日事,一个有知识有理想的韭菜单凭肉眼是很难看出某一个交叉点是否就在趋势上。

我们又可以引入什么指标来避开震荡期呢?后面会继续探讨一下的。

原文链接:http://www.cnblogs.com/yukiwu/p/11816945.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号