雙11臨近的我發現自己真的很窮很窮很窮(重要的問題說三遍)…… 貧窮催人上進。於是我就尋思著在空閑時間自己搗鼓一下錢生錢的游戲是怎麼玩的,畢竟就算註定做韭菜也要做一根有知識有理想的韭菜。 第一個要玩的模型就是股票交易中的均線黃金交叉。 作為一個基礎的韭菜一定聽說過均線黃金交叉原則,也就是說當短期移動 ...
雙11臨近的我發現自己真的很窮很窮很窮(重要的問題說三遍)……
貧窮催人上進。於是我就尋思著在空閑時間自己搗鼓一下錢生錢的游戲是怎麼玩的,畢竟就算註定做韭菜也要做一根有知識有理想的韭菜。
第一個要玩的模型就是股票交易中的均線黃金交叉。
作為一個基礎的韭菜一定聽說過均線黃金交叉原則,也就是說當短期移動平均線向上突破長期移動平均線,表明趨勢見漲,適合買入;相反地如果短期移動平均線向下突破長期移動平均線,表明趨勢看跌,適合賣出。
那麼這個韭菜們都知道的交易原則是不是真的能幫大家賺錢呢?下麵我們以中國平安為例(其實選A股分析還是很尷尬,萬一無論如何都不能賺錢呢……)就建模簡單地驗證一下。
Required Packages
library(quantmod)
library(ggplot2)
library(scales)
Get Data
首先利用 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
Calculate Moving Average
移動平均數通常可分為簡單移動平均數 (SMA),加權移動平均數 (WMA) 和指數移動平均數 (EMA)。
通常我們會選用指數移動平均數。因為移動平均數在一定程度上都會落後於股價的實時趨勢,而指數移動平均數在計算時越新的數據加權比重越大,能更快地反映股價的變化。
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)
}
我們可以將計算結果畫成圖形:
Get Trading Signals
以 5 日和 20 日均線為例,我們可以按照均線黃金交叉原則找到買賣交易點,即某一天的 5 日移動平均數大於 20 日移動平均數時為買入,反之某一天的 5 日移動平均數小於 20 日移動平均數時為賣出。
我們可以將數據分組。當 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)
}
Mock Trading
上面我們已經找出交易點,但其實我們找出這些可能的歷史交易點目的就是為了知道如果嚴格按照這些交易點進行交易能不能賺錢呀?
下麵我們可以模擬一下交易的過程:
假設我們有 100,000 本金,全倉進入,交易費率為 0.3%
mock_trading <- function(signals, capital=100000, 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)
amount <- (amount%/%100)*100
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年的股海沉浮之後,最後我們的本金只有 80,688.14,虧損 19,311.89, 而賺錢的交易只有6次 (買賣合計)。
我們將資產和股價曲線畫成圖形對比可以看出我們在前期的交易中是虧損很多的。一方面是股價走勢確實是跌跌不休 (經歷了 2018 年的韭菜們都知道),那還有沒有交易選擇錯誤的原因呢?
我們將盈利和虧損的交易分別畫出來,就可以看出虧損的交易多在股價尚未形成趨勢還在震蕩,如 2018-08,以及 2018-10-2018-11 期間。所以從數據上來看,均線黃金交叉原則只能對股價已形成趨勢的股票起指導作用。
不過我們也可以樂觀地認為,只要我們能夠避開震蕩期,那麼均線黃金交叉原則還是能夠幫助我們小小賺一筆的。可是今日不知明日事,一個有知識有理想的韭菜單憑肉眼是很難看出某一個交叉點是否就在趨勢上。
我們又可以引入什麼指標來避開震蕩期呢?後面會繼續探討一下的。