找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4350

积分

0

好友

575

主题
发表于 1 小时前 | 查看: 3| 回复: 0

2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含300篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!

引言

在波动剧烈的加密货币市场中,情绪化的追涨杀跌往往是亏损的根源。与其费尽心思猜测市场的顶部或底部,不如让客观的数据来指导交易决策。本文将介绍一个结合了SuperTrend趋势指标与变化率(ROC)过滤器构建的量化交易策略,我们将使用Python来一步步实现这个纪律性强的趋势跟踪系统,看看数据驱动的方法如何在实战中发挥作用。

这个策略在2017年至2025年的历史回测中,展现出了令人印象深刻的表现:总回报率达到了惊人的11,504%,同时将最大回撤控制在59%以内。相比之下,同期简单的买入持有策略虽然也获得了1,296%的回报,但其高达98%的最大回撤对投资者的心理和账户都是巨大的考验。

策略核心思想

这个交易系统的核心逻辑非常直观,旨在捕捉趋势、规避盘整和衰竭:

当市场趋势足够强劲时入场,当上涨动能开始衰退时离场。

具体来说,我们使用SuperTrend指标来判断入场的时机,确认市场是否已经形成明确的趋势;同时,使用ROC指标作为离场的过滤器,当价格上涨的速率开始放缓甚至转为负值时,提示我们可能应该退出观望。

第一步:获取数据

一切量化分析的基础都是可靠的数据。首先,我们需要获取ADA(Cardano)对美元的历史价格数据。这里我们使用yfinance库来获取,并用pandas进行数据管理。

import pandas as pd
import numpy as np
import yfinance as yf
import vectorbt as vbt

# -------------------------
# 下载数据
# -------------------------
symbol = "ADA-USD"  # 交易对:ADA 兑 USD
start_date = "2000-01-01"  # 开始日期
end_date = "2026-01-01"  # 结束日期
interval = "1d"  # 时间间隔:日线

# 使用 yfinance 下载数据
df = yf.download(symbol, start=start_date, end=end_date, interval=interval)

# 保存到本地 CSV 文件
df.to_csv("ADA-USD_clean.csv", index=False)

第二步:计算 SuperTrend 指标

SuperTrend是一个优秀的趋势跟踪指标,它通过平均真实波幅(ATR)来构建动态的上下轨道,能清晰地回答一个问题:当前市场是否处于一个足够强的趋势中?

# SuperTrend 参数设置
SUPERTREND_MULTIPLIER = 3  # 乘数
SUPERTREND_PERIOD = 14  # 周期

def calculate_supertrend(df, period=SUPERTREND_PERIOD, multiplier=SUPERTREND_MULTIPLIER):
    """
    计算 SuperTrend 指标、上轨和下轨

    参数:
        df: 包含 OHLC 数据的 DataFrame
        period: ATR 计算周期
        multiplier: ATR 乘数

    返回:
        添加了 SuperTrend 相关列的 DataFrame
    """
    # 计算中间价
    hl2 = (df['High'] + df['Low']) / 2

    # 计算真实波幅(True Range)
    tr1 = df['High'] - df['Low']
    tr2 = abs(df['High'] - df['Close'].shift())
    tr3 = abs(df['Low'] - df['Close'].shift())
    tr = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1)

    # 计算平均真实波幅(ATR)
    atr = tr.rolling(period).mean()

    # 计算基础上下轨
    upper_basic = hl2 + multiplier * atr
    lower_basic = hl2 - multiplier * atr

    # 初始化最终上下轨
    upper_band = upper_basic.copy()
    lower_band = lower_basic.copy()

    # SuperTrend 趋势列表,True 表示上涨趋势,False 表示下跌趋势
    supertrend = [True]

    for i in range(1, len(df)):
        # 更新上轨
        if df['Close'].iloc[i-1] <= upper_band.iloc[i-1]:
            upper_band.iloc[i] = min(upper_basic.iloc[i], upper_band.iloc[i-1])

        # 更新下轨
        if df['Close'].iloc[i-1] >= lower_band.iloc[i-1]:
            lower_band.iloc[i] = max(lower_basic.iloc[i], lower_band.iloc[i-1])

        # 判断 SuperTrend 方向
        if df['Close'].iloc[i] > upper_band.iloc[i-1]:
            supertrend.append(True)  # 突破上轨,进入上涨趋势
        elif df['Close'].iloc[i] < lower_band.iloc[i-1]:
            supertrend.append(False)  # 跌破下轨,进入下跌趋势
        else:
            supertrend.append(supertrend[-1])  # 保持原有趋势

    df['SuperTrend'] = supertrend
    df['Upper_Band'] = upper_band
    df['Lower_Band'] = lower_band

    return df

def close_above_st(df):
    """判断收盘价是否高于上轨"""
    df = calculate_supertrend(df)
    return df['Close'] > df['Upper_Band']

第三步:计算 ROC 指标

ROC(变化率)指标用于衡量价格在一定时期内的变化速度。它可以帮助我们识别动能的强弱转换。当ROC指标跌破零线时,通常意味着之前的上涨动能正在消退,这可能是一个离场的信号。

# ROC 参数设置
ROC_LEVEL = 0  # ROC 阈值
ROC_PERIOD = 10  # ROC 计算周期

def calculate_roc(df, period=ROC_PERIOD):
    """
    计算收盘价的变化率(ROC)

    参数:
        df: 包含收盘价的 DataFrame
        period: ROC 计算周期

    返回:
        添加了 ROC 列的 DataFrame
    """
    df = df.copy()
    # ROC = (当前价格 - N 周期前价格) / N 周期前价格 * 100
    df['ROC'] = (df['Close'] - df['Close'].shift(period)) / df['Close'].shift(period) * 100
    return df

def roc_below_level(df, level=ROC_LEVEL):
    """判断 ROC 是否低于指定阈值"""
    df = calculate_roc(df)
    return df['ROC'] < level

第四步:定义入场和离场信号

有了指标计算函数,我们就可以将其组合起来,生成具体的交易信号了。入场信号由SuperTrend突破触发,离场信号则由ROC指标恶化触发。

# -------------------------
# 入场条件
# -------------------------
df["Supertrend_Close_Above"] = close_above_st(df)

entry_conditions = [
    'Supertrend_Close_Above',  # 收盘价突破 SuperTrend 上轨
]

# 所有入场条件都满足时,产生入场信号
df['entry_signal'] = df[entry_conditions].all(axis=1)

# -------------------------
# 离场条件
# -------------------------
df["ROC_Below_Level"] = roc_below_level(df)

exit_conditions = [
    'ROC_Below_Level',  # ROC 跌破零线
]

# 所有离场条件都满足时,产生离场信号
df['exit_signal'] = df[exit_conditions].all(axis=1)

第五步:执行回测

策略逻辑构建完成后,最关键的一步就是通过历史数据回测来验证其有效性。我们使用功能强大的vectorbt库进行回测,并考虑交易手续费和滑点,使结果更贴近真实交易。

# -------------------------
# 回测设置
# -------------------------

# 将信号向后移动一天,模拟真实交易中的延迟
shift_entries = df['entry_signal'].shift(1).astype(bool).fillna(False).to_numpy()
shift_exits = df['exit_signal'].shift(1).astype(bool).fillna(False).to_numpy()

# 创建投资组合并执行回测
pf = vbt.Portfolio.from_signals(
    close=df['Open'],  # 使用开盘价执行交易
    entries=shift_entries,  # 入场信号
    exits=shift_exits,  # 离场信号
    init_cash=100_000,  # 初始资金 10 万美元
    fees=0.001,  # 交易手续费 0.1%
    slippage=0.002,  # 滑点 0.2%
    freq='1d'  # 日线频率
)

# -------------------------
# 输出统计结果和可视化
# -------------------------
print(pf.stats())  # 打印回测统计数据
pf.plot().show()  # 绘制回测结果图表

回测结果分析

该策略在2017年11月9日至2025年12月31日期间的表现核心数据如下:

  • 总回报率:11,504%
  • 最大回撤:59%
  • 总交易次数:56次
  • 胜率:43%
  • 盈亏比:1.39

这个结果揭示了一个重要的交易哲学:高胜率并非盈利的唯一途径。虽然该策略的胜率不足50%,但其盈利交易的平均盈利远大于亏损交易的平均亏损(即盈亏比大于1),这使得策略在长期运行中能够累积可观的收益。

与买入持有策略对比

为了更客观地评估策略的表现,我们将其与最简单的“买入并持有”策略进行对比。

# 买入持有策略回测
df_holding = df['Open']
pf_holding = vbt.Portfolio.from_holding(df_holding, init_cash=100_000, fees=0.001)
print(pf_holding.stats())  # 打印买入持有策略的统计数据

买入持有策略的结果是:总回报率 1,296%,最大回撤 98%

对比非常明显。虽然买入持有在长达数年的牛市中也能获得不错的绝对回报,但投资者需要承受资产价值从高点下跌超过98%的心理压力和实际风险,这几乎是毁灭性的。而我们的趋势跟踪策略,在获取更高回报的同时,将最大回撤控制在59%,在风险收益比上表现更优。

总结

这个交易系统的实践给了我们一个清晰的启示:在市场中,你不需要成为能预测未来的先知,只需要成为一个对市场信号做出一致性响应的纪律执行者。

本策略的核心要点可以归纳为:

  1. 趋势确认再入场:利用SuperTrend指标,等待市场展现出足够强度的趋势信号后才入场,避免在震荡行情中频繁交易。
  2. 动能衰退即离场:使用ROC指标作为离场过滤器,一旦检测到价格上涨动能衰竭,便果断离场,锁定利润或减少亏损。
  3. 接受低胜率,追求高盈亏比:不必执着于每笔交易都正确,关键在于确保赚钱的时候比亏钱的时候赚得更多。
  4. 贴近真实的回测:在回测中充分考虑交易手续费和买卖滑点,使得回测结果更具参考价值。

希望这个完整的Python实现案例,能帮助你理解量化交易从思想到代码的完整构建过程。记住,任何策略在投入实盘前都需要结合自身的风险承受能力进行充分的测试、优化与验证。在云栈社区,你可以找到更多志同道合者一起探讨策略优化的可能性。


参考文章与推荐链接已移除。




上一篇:2026年手机价格前瞻:2nm芯片普及或将推动旗舰机型普遍涨价
下一篇:卡塔尔氦气设施遭袭停运,全球芯片供应链面临关键材料短缺危机
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-15 17:01 , Processed in 0.475027 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表