学习python量化不要迷信指标MACDRSI都赚不到钱

“弱水三千,只取一瓢饮。”我不贪图能吃到从行情的起涨点到最高点的全部收益,只要尝到其中的一小段就足够了。这是策略设想的最初本意。

一、最初思路

当行情位于上升趋势时,MACD的红柱会一根比一根长,而在下跌趋势时,绿柱则会一根比一根长。MACD 的红绿柱展示了多空力量强弱情况,所以,我们选择在MACD出现红柱时进场,出现绿柱时离场。

二、写出代码

今天我们选择用akshare来获取数据,用backtrader来回测。

1、导入模块

import backtrader as bt
import akshare as ak
import pandas as pd

2、获取行情数据、转换为Backtrader 数据格式

# 获取股票数据
df = ak.stock_zh_a_hist('600863', start_date='20200101', end_date='20240601')

# 确保 '日期' 列被转换为 'datetime' 列,并且是 pandas 的 Timestamp 类型
df['datetime'] = pd.to_datetime(df['日期'])

# 需要将 akshare 返回的列名映射为 backtrader 能够识别的列名
data_columns = {
    '开盘': 'open',
    '收盘': 'close',
    '最高': 'high',
    '最低': 'low',
    '成交量': 'volume'
}

# 映射列名
for ak_name, bt_name in data_columns.items():
    df[bt_name] = df[ak_name]

# 转换为 Backtrader 数据格式
data = bt.feeds.PandasData(
    dataname=df,
    datetime='datetime',  # 确保 datetime 列名正确
    open='开盘',          # 列名映射
    high='最高',
    low='最低',
    close='收盘',
    volume='成交量'
)

3、编写策略:

class MACDStrategy(bt.Strategy):
    # 定义策略参数
    params = (
        ('fast_period', 12),
        ('slow_period', 26),
        ('signal_period', 9),
    )

    def __init__(self):
        # 初始化MACD指标
        self.macd = bt.indicators.MACD(self.data.close,
                                       period_me1=self.params.fast_period,
                                       period_me2=self.params.slow_period,
                                       period_signal=self.params.signal_period)
        # 获取MACD直方图
        self.macd_hist = self.macd.macd - self.macd.signal

    def next(self):
        # 获取当前和前一个周期的MACD直方图值
        current_hist = self.macd_hist[0]
        previous_hist = self.macd_hist[-1]

        # MACD柱子由绿变红时买入
        if current_hist > previous_hist and previous_hist <= 0 and current_hist > 0:
            if self.position.size == 0:
                self.buy()

        # MACD柱子缩短且由正变负时卖出
        elif current_hist < previous_hist and previous_hist > 0 and current_hist <= 0:
            if self.position:
                self.close()

4、将数据及策略导入backtrader中进行回策

# 创建Cerebro引擎
cerebro = bt.Cerebro()

# 将数据添加到Cerebro引擎
cerebro.adddata(data)

# 添加策略
cerebro.addstrategy(MACDStrategy)

# 设置初始资金
initial_capital= 100000

# 设置交易费用和滑点
cerebro.broker.setcash(initial_capital)
cerebro.broker.setcommission(commission=0.001)

# 运行回测
cerebro.run()

# 打印结果
print(f"Final Portfolio Value: {cerebro.broker.getvalue()}")
print(f"Total Return: {(cerebro.broker.getvalue() - initial_capital) / initial_capital * 100:.2f}%")
cerebro.plot()

三、运行程序,查看回测结果

学习python量化不要迷信指标MACDRSI都赚不到钱

学习python量化不要迷信指标MACDRSI都赚不到钱

结果怎么样?辛辛苦苦四年半,最后还没赚到1元钱。难道是等出现绿柱时抛,有点儿卖完了,那等红柱一开如缩短就开始逃跑吧。修改一下卖出条件:

        elif current_hist < previous_hist:
            if self.position:
                self.close()

但是结果反而亏了几毛:

学习python量化不要迷信指标MACDRSI都赚不到钱

四、优化策略:MACD+RSI

macd的红绿柱虽能表示多空力量,但单独使用它来进行交易还是有局限性的。下面来改进优化策略,加上RSI强弱指标,在超卖区买入,超买区卖出。完整代码如下:

# MACD红柱买入策略:MACD柱子绿翻红,全仓买入,当MACD红柱翻绿,全仓卖出。
# 本策略仅用于学习,不支持实盘

import backtrader as bt
import akshare as ak
import pandas as pd

# 获取股票数据
df = ak.stock_zh_a_hist('600863', start_date='20200101', end_date='20230101')

# 确保 '日期' 列被转换为 'datetime' 列,并且是 pandas 的 Timestamp 类型
df['datetime'] = pd.to_datetime(df['日期'])

# 需要将 akshare 返回的列名映射为 backtrader 能够识别的列名
data_columns = {
    '开盘': 'open',
    '收盘': 'close',
    '最高': 'high',
    '最低': 'low',
    '成交量': 'volume'
}

# 映射列名
for ak_name, bt_name in data_columns.items():
    df[bt_name] = df[ak_name]

# 转换为 Backtrader 数据格式
data = bt.feeds.PandasData(
    dataname=df,
    datetime='datetime',  
    open='开盘',         
    high='最高',
    low='最低',
    close='收盘',
    volume='成交量'
)

# 定义MACD策略
class MACDStrategy(bt.Strategy):
    # 定义策略参数
    params = (
        ('fast_period', 12),
        ('slow_period', 26),
        ('signal_period', 9),
        ('rsi_period', 14),
        ('rsi_upper', 70),
        ('rsi_lower', 30),
    )

    def __init__(self):
        # 初始化MACD指标
        self.macd = bt.indicators.MACD(self.data.close,
                                       period_me1=self.params.fast_period,
                                       period_me2=self.params.slow_period,
                                       period_signal=self.params.signal_period)
        # 获取MACD直方图
        self.macd_hist = self.macd.macd - self.macd.signal
        self.rsi = bt.indicators.RSI(self.data.close, period=self.params.rsi_period)

    def next(self):
        # 获取当前和前一个周期的MACD直方图值
        current_hist = self.macd_hist[0]
        previous_hist = self.macd_hist[-1]
        current_rsi = self.rsi[0]

        # MACD柱子由绿变红时买入
        if current_hist > previous_hist and previous_hist <= 0 and current_hist > 0 and current_rsi < self.params.rsi_lower:
            if self.position.size == 0:
                self.buy()

        # MACD柱子缩短且由正变负时卖出
        elif current_hist < previous_hist and previous_hist > 0 and current_hist <= 0 and current_rsi > self.params.rsi_upper:
            if self.position:
                self.close()

# 创建Cerebro引擎
cerebro = bt.Cerebro()

# 将数据添加到Cerebro引擎
cerebro.adddata(data)

# 添加策略
cerebro.addstrategy(MACDStrategy)

# 设置初始资金
initial_capital= 100000

# 设置交易费用和滑点
cerebro.broker.setcash(initial_capital)
cerebro.broker.setcommission(commission=0.001)

# 运行回测
cerebro.run()

# 打印结果
print(f"Final Portfolio Value: {cerebro.broker.getvalue()}")
print(f"Total Return: {(cerebro.broker.getvalue() - initial_capital) / initial_capital * 100:.2f}%")
cerebro.plot()
学习python量化不要迷信指标MACDRSI都赚不到钱

结果依然没有赚到钱,又适当修改了一下参数,还是没有什么用。

五、总结

在股市中,仅仅依据某个指标很难保证一定能赚到钱的。指标通常是基于价格和成交量等数据计算得出的,而影响价格的因素实在太多、例如各种消息、投资者的情绪、各种政策的出台、资金的流向等等,所以指标常常在某个时间段有效,过了一段时间又会失效。

以后有机会,再回测一下MACD的顶底背离吧。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/73454
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 2024 年 7 月 10 日
下一篇 2024 年 7 月 10 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注