[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 11 - 那个很常用到的 useEffect

>>:  30天打造品牌特色电商网站 Day.12 一定要有的导览列

javascript函式教学1

1.函式基础 我们经常使用alert();这可以叫出一个警告视窗,alert就是一个系统预先写好的程...

DAY27 MongoDB Time Series Collection

DAY27 MongoDB Time Series Collection 什麽是 Time seri...

Day 22 - Rancher Fleet 架构介绍

本文将於赛後同步刊登於笔者部落格 有兴趣学习更多 Kubernetes/DevOps/Linux 相...

Day4 资料储存 - file storage基础

file storage 一种让人易於了解的储存方式 在学完Block storage之後,是否发现...

[ Day 6] - 阵列与物件的混合使用

阵列与物件混合使用 阵列与物件的混合使用范例 直接以范例说明,需要设计的范例资料上 有两间店,分别有...