iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0
AI & Data

從零開始的套牢生活 - AI股票預測系統系列 第 21

[Day 21] 策略(Strategy)

一、策略

在1880年代,科學家提倡使用占星術預測未來是很流行的,但到了現代科學,尤其是做交易,我們還是發明了很多,類似占星術的工具,像是震盪指標、Fibonacci序列、黃金比例、elliot wave 等等。雖然背後有明確數學定義,但其能獲利的根本的原因卻是不明的。占星術和技術指標,其實是非常相似的,不是說不能用技術指標,只是在用的時候,我們要確保從統計的角度,有真的達到優化的效果,不然技術指標不就跟占星術沒什麼差別了 ! - From https://www.finlab.tw/quantitative-trading/

為什麼要使用策略?

策略簡單來說就是一個全自動的投資機器,只要給予一些規則,之後策略就會給定該進、出場的時機。

  • 理性投資,避免因人性恐慌而導致損失。
  • 績效驗證,可透過歷史資料進行驗證。

二、常用策略

All in

非常簡單粗暴,把所有錢一次性砸進去股票。
值得注意的是ETF型股票因為是和台股指數掛勾,所以在一定程度上可以反映台股大盤的狀況,
加上無腦投資的特性,如果一個策略投報率和風險都比All in ETF還糟,那這個策略基本上可以直接丟了。

class Allin(ConsStrategy):
    # Class variable for parameters tuning
    def init(self):
        super().init()
        self.conservative = False
        self.tag = True

    def next(self):
        if self.tag:
            self.buy()
            self.tag = False

「只買不賣」Continue Holding

常常在新聞看到的策略,在每月首個交易日買一張股票。
同樣是無腦投資,如果一個策略投報率和風險都比Continue Holding還糟,那這個策略還是可以丟了。

class Allin(ConsStrategy):
    # Class variable for parameters tuning
    def init(self):
        super().init()
        self.conservative = False
        self.tag = True

    def next(self):
        if self.tag:
            self.buy()
            self.tag = False

MA Crossover

短期線突破長期線(黃金交叉),進場。 長期線突破短期線(死亡交叉),出場。

這個法則其實就是在說明:「黑鮪魚,去頭去尾,只吃魚肚」的道理,不用買在最低,也不用賣在最高,只要獲取中間的獲利就好。

# SMA
# https://smart.businessweekly.com.tw/Reading/IndepArticle.aspx?id=37313
# -----------------------------------
class SmaCrossCons(ConsStrategy):
    # Class variable for parameters tuning
    fast_days = 5
    slow_days = 15

    def init(self):
        super().init()

        self.fast_line = self.I(ta.sma, self.data.Close.s, self.fast_days)
        self.slow_line = self.I(ta.sma, self.data.Close.s, self.slow_days)
        self.conservative = True

    def next(self):
        if crossover(self.fast_line, self.slow_line):
            if len(self.trades) > 0:
                self.trades[0].close()

            self.buy()
        elif crossover(self.slow_line, self.fast_line):
            if len(self.trades) > 0:
                self.trades[0].close()

            if self.conservative == False:
                self.sell()

MACD Crossover

當柱狀圖由負翻正,快線往上突破慢線,被視為黃金交叉(預測市場會上漲),
表示後續可能會有一波漲幅,投資人通常視為買入信號。

當快線向下跌破慢線,也就是柱狀圖由正轉負,被視死亡交叉(預測市場會下跌),
表示後續可能會有一波跌幅可能,投資人通常視為賣出信號。

# MacdCrossCons
# https://rich01.com/what-is-macd-indicator/
# -----------------------------------
class MacdCrossCons(ConsStrategy):
    # Class variable for parameters tuning
    fast_days = 12
    slow_days = 26
    sig_days = 9

    def init(self):
        super().init()

        self.MACD = self.I(
            ta.macd,
            self.data.Close.s,
            self.fast_days,
            self.slow_days,
            self.sig_days,
            plot=False,
        )

        self.OSC = self.I(
            lambda A: A[2],
            self.MACD,
            name=f"Hist({self.sig_days},{self.fast_days},{self.slow_days})",
            plot=True,
        )

        self.conservative = True

    def next(self):
        if crossover(self.OSC, 0):
            if len(self.trades) > 0:
                self.trades[0].close()

            self.buy()
        elif crossover(0, self.OSC):
            if len(self.trades) > 0:
                self.trades[0].close()

            if self.conservative == False:
                self.sell()


KDJ Check

在某一段期間內股價上漲,走多頭走勢,KD值會往上漲,因此KD值位於50以上,表示多方佔上風,反之則是空方,如果在50上下徘徊,則是多空尚在交戰,趨勢仍未明的階段。

而各位如果能懂得上述KD值上限100與下限0的狀況,應該不難理解在常理當中,無論是K值或D值,越接近100或0,越可能出現反轉的趨勢,畢竟股價不可能一直不間斷的上漲或下跌。

class KCheckCons(ConsStrategy):
    # Class variable for parameters tuning
    kd_days = 14
    high_cape = 80
    low_cape = 20

    def init(self):
        super().init()

        self.KDJ = self.I(
            ta.kdj,
            high=self.data.High.s,
            low=self.data.Low.s,
            close=self.data.Close.s,
            length=self.kd_days,
            plot=False,
        )

        self.K = self.I(lambda A: A[0], self.KDJ, plot=True)
        self.D = self.I(lambda A: A[1], self.KDJ, plot=True)

        self.conservative = True

    def next(self):
        # print(self.K.shape)
        if crossover(self.low_cape, self.K):
            if len(self.trades) > 0:
                self.trades[0].close()

            self.buy()
        elif crossover(self.K, self.high_cape):
            if len(self.trades) > 0:
                self.trades[0].close()

            if self.conservative == False:
                self.sell()

KD Crossover

和MA Crossover差不多意思,利用KD之間的敏感程度決定進出場時機。

class KDCrossCons(ConsStrategy):
    # Class variable for parameters tuning
    kd_days = 14

    def init(self):
        super().init()

        self.KDJ = self.I(
            ta.kdj,
            high=self.data.High.s,
            low=self.data.Low.s,
            close=self.data.Close.s,
            length=self.kd_days,
            plot=False,
        )

        self.K = self.I(lambda A: A[0], self.KDJ, plot=True)
        self.D = self.I(lambda A: A[1], self.KDJ, plot=True)
        # self.D = self.I(np.take, self.KDJ, 1, plot=True)
        # self.D = self.I(SMA, self.data.Close, self.kd_days, plot=False)

        self.conservative = True

    def next(self):
        # print(self.K.shape)
        if crossover(self.K, self.D):
            if len(self.trades) > 0:
                self.trades[0].close()

            self.buy()
        elif crossover(self.D, self.K):
            if len(self.trades) > 0:
                self.trades[0].close()

            if self.conservative == False:
                self.sell()

Bias Check

乖離率策略,觀察股價偏離移動平均線(MA線)的程度來決定是否進場。 負乖離表示股價低於過去一段時間平均價,意味著股價相對過去低,所以選擇進場。 正乖離表示股價高於過去一段時間平均價,意味著股價相對過去高,所以選擇出場。

簡單來說,漲到太高代表快跌了,跌太低代表快漲了,然而你買的時候還是會跌

class BiasCheckCons(ConsStrategy):
    # Class variable for parameters tuning
    sma_days = 10
    high_cape = 0.08
    low_cape = -0.07

    def init(self):
        super().init()

        self.Bias = self.I(
            ta.bias,
            close=self.data.Close.s,
            length=self.sma_days,
            plot=False,
        )

        self.conservative = True

    def next(self):
        # print(self.K.shape)
        if crossover(self.Bias, self.high_cape):
            if len(self.trades) > 0:
                self.trades[0].close()

            self.buy()
        elif crossover(self.low_cape, self.Bias):
            if len(self.trades) > 0:
                self.trades[0].close()

            if self.conservative == False:
                self.sell()

上一篇
[Day 20] 回測與報表
下一篇
[Day 22] 籌碼策略
系列文
從零開始的套牢生活 - AI股票預測系統30

尚未有邦友留言

立即登入留言