R與金錢遊戲:均線黃金交叉2

上一篇分析已經得知均線黃金交叉原則並不適用於震盪期,那有什麼辦法能夠規避震盪期呢或者說有什麼辦法能夠減小無腦跟的損失?咱們繼續玩一下。html

Required Packages


library(quantmod)
library(ggplot2)
library(scales)

Postpone Trading


第一個嘗試的方法是推遲買入時間。post

若股價處於震盪期,那麼有可能就是今天漲了明天跌。咱們能夠在買入信號出現的時候暫時抑制心裏買買買的衝動,推遲個3-5天觀察一下股價是否還處於上升期。如果,咱們再大膽出手。ui

######
buy <- which(signals$Signal == 1)
sell <- which(signals$Signal == -1)
for(ii in 1:length(buy)){
  tmp <- 0
  index <- buy[ii]
  signals$Signal[index] <- 0
  for(jj in 1:delay_days) 
    tmp <- tmp + signals$Trade[index + jj]
  if(tmp == delay_days) 
    signals$Signal[index + delay_days] <- 1
  else
    signals$Signal[sell[ii]] <- 0
}
######

假設咱們在買入信號出現的時候推遲 3 天且這 3 天內短時間均線依然高於長期均線,則出手買入。那麼從 2018-01-01 開始至 2019-11-07(上次分析的截止時間) 至今一共有 22 次交易 (買賣合計),相較於上一篇的分析中少了 8 次交易。本金最後爲 92,293.10,虧損 7,706.90。虧損率由 19% 降爲 7%。另外從圖中咱們也能夠看見推遲買入也減小了在 2018 年的頻繁交易
01
023d

Early Termination


第二個嘗試的方法是提早終止交易,俗稱止損。code

咱們能夠設置止損線,即股價跌破某一個位置的時候不管是否爲死亡黃金交叉都選擇賣出,即時止損。htm

#####
buy <- which(signals$Signal == 1)
sell <- which(signals$Signal == -1)
iteration <- min(length(buy), length(sell))
if(sell_ratio > 0) {
  for(ii in 1:iteration){
    buy_index <- buy[ii]
    sell_index <- sell[ii]
    for(jj in buy_index:sell_index){
      if(signals$Value[jj]/signals$Value[buy_index] < 1- (sell_ratio - 0.02)) {
        signals$Signal[sell_index] <- 0
        signals$Signal[jj] <- -1
        signals$Trade[jj] <- 0
        break
      }
    }
  }
}
#####

假設咱們將止損額設爲 7%, 即如今比買入價低於 7% 則賣出。那麼從 2018-01-01 開始至 2019-11-07(上次分析的截止時間) 至今一共有 30 次交易 (買賣合計),盈利交易一共有 6 次。本金最後爲 84,796.95,虧損 15,203.05。虧損率由 19% 降爲 15%。
03
04blog

Differentiate


咱們都知道均線是延後表達的, 咱們沒有辦法 100% 預判此時此刻是否是在震盪期內。可是一般震盪期內的均線大部分是趨於平緩的(即斜率接近於零),而趨勢期內的均線是傾斜的,並且越傾斜(斜率越大)上漲的空間也越大。該表現用長期均線斷定更爲準確。遊戲

咱們利用均線的斜率過濾一些表現爲平緩趨勢的買入點,即只有當買入信號出現且此時的均線斜率大於某值時纔買入,不然不作交易。get

#####
switch(filter_type,
       "NO_FILTER" = print("No Filter!"),
       "DIFF_SHORTTERM_GREATER_THAN_POINT_5" = signals <- signals[-c(which(signals$Signal == 1 & signals$Diff_1 < 0.5), 
                                                                    which(signals$Signal == 1 & signals$Diff_1 < 0.5) + 1),]
)
#####

假設咱們將買入過濾器設爲5日均線的斜率大於 0.5 (傾斜角約爲 26.5°), 即買入信號的5日均線的斜率大於 0.5 才真正地買入。那麼從 2018-01-01 開始至 2019-11-07(上次分析的截止時間) 至今一共有 20 次交易 (買賣合計),盈利交易一共有 6 次。本金最後爲 99,788.09,虧損 211.91。虧損率由 19% 降爲 0.02%。從圖中咱們也能夠看見過濾器過濾了一些震盪期中的交易。
05
06it

Questions


這些方法都能在必定程度上讓咱們避開在震盪期交易,可是若是要確切的使用上這些方法,那麼具體的數字應該設置爲多少纔是合適的呢,即針對某一隻股票應該推遲多少天買入避開震盪期呢?或者設置多少的止損線呢?又或者均線的斜率設置爲多少做爲過濾呢?之後有機會再用一些更先進的方法玩一下。

相關文章:R與金錢遊戲:均線黃金交叉1

Code


get_signals <- function(data, mas_1=5, mas_2=20, delay_days= 3, sell_ratio = 0.07, filter_type="NO_FILTER") {
  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)]
  signals <- data.frame(Index=index(ma_data), coredata(ma_data))
  signals$Trade <- ifelse(signals[,c(ma_name_1)] > signals[,c(ma_name_2)], 1, 0)
  signals <- signals[-c(1:mas_2),]
  signals$Signal <- c(signals$Trade[1],diff(signals$Trade))
  signals$Diff_1 <- c(NA, diff(signals[,c(ma_name_1)]))
  signals$Diff_2 <- c(NA, diff(signals[,c(ma_name_2)]))

  ##### 
  ##### add code block here
  #####

  signals <- signals[which(signals$Signal != 0),]
  if(length(signals$Index) < 1) {
    print("No trading signal!")
    return (signals)
  }
  if(nrow(signals)%%2 == 1) {
    if(signals$Trade[1] == 1)
      signals <- signals[-c(nrow(signals)),]
    else
      signals <- signals[-c(1),]
  }
  if(signals$Trade[1] == 0) {
    signals <- signals[-c(nrow(signals)),]
    signals <- signals[-c(1),]
  }
  signals <- signals[,-which(names(signals)%in% c(ma_name_1, ma_name_2, "Diff_1", "Diff_2"))]
  return (signals)
}
相關文章
相關標籤/搜索