双11临近的我发现本身真的很穷很穷很穷(重要的问题说三遍)……api
贫穷催人上进。因而我就寻思着在空闲时间本身捣鼓一下钱生钱的游戏是怎么玩的,毕竟就算注定作韭菜也要作一根有知识有理想的韭菜。ui
第一个要玩的模型就是股票交易中的均线黄金交叉。3d
做为一个基础的韭菜必定据说过均线黄金交叉原则,也就是说当短时间移动平均线向上突破长期移动平均线,代表趋势见涨,适合买入;相反地若是短时间移动平均线向下突破长期移动平均线,代表趋势看跌,适合卖出。code
那么这个韭菜们都知道的交易原则是否是真的能帮你们赚钱呢?下面咱们以中国平安为例(其实选A股分析仍是很尴尬,万一不管如何都不能赚钱呢……)就建模简单地验证一下。blog
library(quantmod) library(ggplot2) library(scales)
首先利用 quantmod 包下载股价数据。股票的代码能够在雅虎财经查到。游戏
stock_code <- "601318.SS" start <- as.Date("2018-01-01") end <- as.Date("2020-01-01") stock <- getSymbols(stock_code, from=start, auto.assign=FALSE) names(stock) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted") stock <- stock[paste(start, end, sep='/')]$Close
移动平均数一般可分为简单移动平均数 (SMA),加权移动平均数 (WMA) 和指数移动平均数 (EMA)。get
一般咱们会选用指数移动平均数。由于移动平均数在必定程度上都会落后于股价的实时趋势,而指数移动平均数在计算时越新的数据加权比重越大,能更快地反映股价的变化。it
ma <- function(data, mas=c(5, 20, 60)) { ma_data <- data for(m in mas) { ma_data <- merge(ma_data, EMA(data, m)) } ma_data <- na.locf(ma_data, fromLast = TRUE) names(ma_data) <- c('Value', paste('MA', mas, sep='')) return(ma_data) }
咱们能够将计算结果画成图形:
io
以 5 日和 20 日均线为例,咱们能够按照均线黄金交叉原则找到买卖交易点,即某一天的 5 日移动平均数大于 20 日移动平均数时为买入,反之某一天的 5 日移动平均数小于 20 日移动平均数时为卖出。ast
咱们能够将数据分组。当 5 日均线大于 20 日均线时为 “buy”; 当 5 日均线小于 20 日均线时为 “sell”。 其中 “buy” 和 “sell” 是以不定数量间隔出现的,那么每一段中第一个 “buy” 出现的时候为买入, 第一个 “sell” 出现的时候为卖出。在模拟交易的时候为了方便计算利润,咱们将买入设为第一次交易,卖出设为最后一次交易。
若是咱们一直依照均线黄金交叉原则,那么从 2018-01-01 开始至今一共有 30 次交易 (买卖合计)。
get_signals<- function(data, mas_1=5, mas_2=20) { if(mas_1 == 0) ma_name_1 <- "Value" else ma_name_1 <- paste('MA', mas_1, sep='') ma_name_2 <- paste('MA', mas_2, sep='') ma_data <- data[, c("Value", ma_name_1, ma_name_2)] #please calculate ma value before and get a dataframe like the section above down_data <- ma_data[which(ma_data[, c(ma_name_1)] > ma_data[, c(ma_name_2)]), c("Value")] up_data <- ma_data[which(ma_data[, c(ma_name_1)] < ma_data[, c(ma_name_2)]), c("Value")] result <- merge(down_data, up_data) names(result) <- c("buy", "sell") result <- fortify(result, melt=TRUE) result<- result[-which(is.na(result$Value)),] signals <- result[order(result$Index),] signals$Signal <- ifelse(signals$Series == "buy", 1, 0) signals$Signal <- c(ifelse(signals$Series[1] == "buy", 1, -1),diff(signals$Signal)) signals <- signals[which(signals$Signal != 0),] #delete odd rows if(nrow(signals)%%2 == 1) { if(signals$Series[1] == "buy") signals <- signals[-c(nrow(signals)),] else signals <- signals[-c(1),] } if(signals$Series[1] == "sell") { signals <- signals[-c(nrow(signals)),] signals <- signals[-c(1),] } return (signals) }
上面咱们已经找出交易点,但其实咱们找出这些可能的历史交易点目的就是为了知道若是严格按照这些交易点进行交易能不能赚钱呀?
下面咱们能够模拟一下交易的过程:
假设咱们有 10,000 本金,全仓进入,交易费率为 0.3%
mock_trading <- function(signals, capital=10000, position=1, fee=0.003){ amount <- 0 cash <- capital * position ticks <- data.frame() for(ii in 1:nrow(signals)){ row <- signals[ii,] if(row$Series == "buy") { amount <- floor((cash/(1+fee))/row$Value) cash <- cash - amount * row$Value - (amount * row$Value) * fee } if(row$Series == "sell") { cash <- cash + amount * row$Value - (amount * row$Value) * fee amount <- 0 } row$cash <- cash row$amount <- amount row$asset<- cash + amount * row$Value row$fee <- (amount * row$Value) * fee ticks<-rbind(ticks, row) } ticks$diff <- c(0, diff(ticks$asset)) rise <- ticks[c(which(ticks$diff > 0)-1, which(ticks$diff > 0)),] rise <- rise[order(rise$Index),] fall <- ticks[c(which(ticks$Series=="sell" & ticks$diff < 0)-1, which(ticks$Series=="sell" & ticks$diff < 0)),] fall <- rise[order(fall$Index),] return(list( ticks = ticks, rise = rise, fall = fall )) }
若是严格按照均线黄金交叉原则,那么通过2年的股海沉浮以后,最后咱们的本金只有 7962.18,亏损 2037.82, 而赚钱的交易只有6次 (买卖合计)。
咱们将资产和股价曲线画成图形对比能够看出咱们在前期的交易中是亏损不少的。一方面是股价走势确实是跌跌不休 (经历了 2018 年的韭菜们都知道),那还有没有交易选择错误的缘由呢?
咱们将盈利和亏损的交易分别画出来,就能够看出亏损的交易多在股价还没有造成趋势还在震荡,如 2018-08,以及 2018-10-2018-11 期间。因此从数据上来看,均线黄金交叉原则只能对股价已造成趋势的股票起指导做用。
不过咱们也能够乐观地认为,只要咱们可以避开震荡期,那么均线黄金交叉原则仍是可以帮助咱们小小赚一笔的。但是今日不知明日事,一个有知识有理想的韭菜单凭肉眼是很难看出某一个交叉点是否就在趋势上。
咱们又能够引入什么指标来避开震荡期呢?后面会继续探讨一下的。