社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

年化收益26.6%, 最大回撤5.06%, 年化夏普率1.36,aroon指标在期货里的应用案例,附python代码

七年实现财富自由 • 1 周前 • 51 次点击  
原创内容第970篇,专注AGI+,AI量化投资、个人成长与财富自由。
从量化指标的角度,有趋势指标和震荡指标,通过历史的价量数据去描述价格运动的状态。——部分有统计学的逻辑基础。
咱们在使用一个或多个指标时,一定要了解指标背后的计算公式,最好自己上手计算一下,这样就会理解这个指标的应用,适用场景及局限性。
今天咱们来说说aroon指标,并基于这个指标做一些回测。
aroon指标(又称阿隆指标)是由技术分析大师图莎尔·钱德(Tushar Chande)于1995年提出的趋势跟踪类指标。其名称源于梵文“Aroon”,意为“黎明之光”,寓意其能早期探测趋势的萌芽
相较于MACD、RSI等传统指标,Aroon因使用者较少且侧重“时间维度”而非价格波动,被认为在趋势识别上更具独特性和稳定性。
  1. Aroon Up(上升线)
    = [(N - 距离最近最高价的天数) / N] × 100
    衡量当前价格与近期最高价的“时间距离”,数值越高说明上升趋势越强18

  • 示例:若周期N=25天,今日创最高价,则Aroon Up = 100;若最高价出现在10天前,则Aroon Up = (25-10)/25×100 = 608

  • Aroon Down(下降线)
    = [(N - 距离最近最低价的天数) / N] × 100
    衡量当前价格与近期最低价的“时间距离”,数值越高说明下降趋势越强49

  • Aroon Oscillator(震荡线)
    = Aroon Up - Aroon Down
    用于量化多空力量差值,正值表示上升主导,负值表示下降主导。

  • 策略逻辑:

    开仓信号:

    该策略使用两种主要的开仓信号:

    • 交叉信号
      • 多头信号:Aroon Up从下方穿越Aroon Down
      • 空头信号:Aroon Down从下方穿越Aroon Up

    平仓信号:

    平仓信号基于Aroon指标的反向交叉:

    • 平多信号:Aroon Down从下方穿越Aroon Up
    • 平空信号:Aroon Up从下方穿越Aroon Down

    这些反向信号往往代表趋势可能发生转变,是获利了结的好时机。

    止损机制:

    该策略使用基于百分比的固定止损:

    • 止损百分比设定为1.2%(STOP_LOSS_PCT = 1.2)
    • 多头止损:当价格下跌超过入场价格的1.2%时触发
    • 空头止损:当价格上涨超过入场价格的1.2%时触发
    from tqsdk import TqApi, TqAuth, TqBacktest, TargetPosTask, BacktestFinishedimport pandas as pdfrom datetime import date
    from tqsdk import TqApi, TqAuth,TqBacktest,TargetPosTaskimport pandas as pdfrom datetime import dateimport osdef get_env_var(name, default=None):    value = os.environ.get(name)    if value is None and default is None:        raise EnvironmentError(f"环境变量 {name} 未设置")     return value or defaultusername = get_env_var('TQ_USERNAME')password = get_env_var('TQ_PASSWORD')
    # ===== 全局参数设置 =====SYMBOL = "SHFE.au2306"  # 黄金期货合约POSITION_SIZE = 30  # 持仓手数START_DATE = date(2023220)  # 回测开始日期END_DATE = date(202355)  # 回测结束日期
    # Aroon指标参数AROON_PERIOD = 10  # Aroon计算周期AROON_UPPER_THRESHOLD = 75  # Aroon上线阈值AROON_LOWER_THRESHOLD = 25  # Aroon下线阈值
    # 风控参数STOP_LOSS_PCT = 1.2  # 止损百分比
    # ===== 全局变量 =====position = 0  # 当前持仓entry_price = 0  # 入场价格trades = []  # 交易记录
    # ===== 主程序 =====print(f"开始回测 {SYMBOL} 的Aroon指标策略...")print(f"参数: Aroon周期={AROON_PERIOD}, 上阈值={AROON_UPPER_THRESHOLD}, 下阈值={AROON_LOWER_THRESHOLD}")print(f"回测期间: {START_DATE} 至 {END_DATE}")
    try:    # 创建API实例    api = TqApi(backtest=TqBacktest(start_dt=START_DATE, end_dt=END_DATE),                auth=TqAuth(username, password))
        # 订阅K线数据    klines = api.get_kline_serial(SYMBOL, 60 * 60 * 24)  # 日K线    target_pos = TargetPosTask(api, SYMBOL)
        # 主循环    while True:        api.wait_update()
            if api.is_changing(klines.iloc[-1], "datetime"):            # 确保有足够的数据            if len(klines) < AROON_PERIOD + 10:                continue
                # ===== 计算Aroon指标 =====            # 找出最近N周期内最高价和最低价的位置            klines['rolling_high'] = klines['high'].rolling(window=AROON_PERIOD).max()            klines['rolling_low'] = klines['low'].rolling(window=AROON_PERIOD).min()
                # 初始化Aroon Up和Aroon Down数组            aroon_up = []            aroon_down = []
                # 遍历计算每个时间点的Aroon值            for i in range(len(klines)):                if i < AROON_PERIOD - 1:                    aroon_up.append(0)                    aroon_down.append(0)                    continue
                    period_data = klines.iloc[i - AROON_PERIOD + 1:i + 1]                # 明确指定skipna=True来处理NaN值                high_idx = period_data['high'].fillna(float('-inf')).argmax()                low_idx = period_data['low'].fillna(float('inf')).argmin()
                    days_since_high = i - (i - AROON_PERIOD + 1 + high_idx)                days_since_low = i - (i - AROON_PERIOD + 1 + low_idx)
                    aroon_up.append(((AROON_PERIOD - days_since_high) / AROON_PERIOD) * 100)                aroon_down.append(((AROON_PERIOD - days_since_low) / AROON_PERIOD) * 100)
                # 将Aroon值添加到klines            klines['aroon_up'] = aroon_up            klines['aroon_down'] = aroon_down
                # 计算Aroon Oscillator (可选)            klines['aroon_osc'] = klines[ 'aroon_up'] - klines['aroon_down']
                # 获取当前和前一个周期的数据            current_price = float(klines.close.iloc[-1])            current_time = pd.to_datetime(klines.datetime.iloc[-1], unit='ns')            current_aroon_up = float(klines.aroon_up.iloc[-1])            current_aroon_down = float(klines.aroon_down.iloc[-1])
                prev_aroon_up = float(klines.aroon_up.iloc[-2])            prev_aroon_down = float(klines.aroon_down.iloc[-2])
                # 输出当前指标值,帮助调试            print(f"当前K线: {current_time.strftime('%Y-%m-%d')}, 价格: {current_price:.2f}")            print(f"Aroon Up: {current_aroon_up:.2f}, Aroon Down: {current_aroon_down:.2f}")
                # ===== 止损检查 =====            if position != 0 and entry_price != 0:                if position > 0:  # 多头止损                    profit_pct = (current_price / entry_price - 1) * 100                    if profit_pct < -STOP_LOSS_PCT:                        print(f"触发止损: 当前价格={current_price}, 入场价={entry_price}, 亏损={profit_pct:.2f}%")                        target_pos.set_target_volume(0)                        trades.append({                            'type''止损平多',                            'time': current_time,                            'price': current_price,                            'profit_pct': profit_pct                        })                        print(f"止损平多: {current_time}, 价格: {current_price:.2f}, 亏损: {profit_pct:.2f}%")                        position = 0                        entry_price = 0                        continue
                    elif position 0:  # 空头止损                    profit_pct = (entry_price / current_price - 1) * 100                    if profit_pct < -STOP_LOSS_PCT:                        print(f"触发止损: 当前价格={current_price}, 入场价={entry_price}, 亏损={profit_pct:.2f}%")                        target_pos.set_target_volume(0)                        trades.append({                            'type''止损平空',                            'time': current_time,                            'price': current_price,                            'profit_pct': profit_pct                        })                        print(f"止损平空: {current_time}, 价格: {current_price:.2f}, 亏损:  {profit_pct:.2f}%")                        position = 0                        entry_price = 0                        continue
                # ===== 交易信号判断 =====            # 1. Aroon交叉信号            aroon_cross_up = prev_aroon_up < prev_aroon_down and current_aroon_up > current_aroon_down            aroon_cross_down = prev_aroon_up > prev_aroon_down and current_aroon_up < current_aroon_down
                # 2. 强势信号            strong_up = current_aroon_up > AROON_UPPER_THRESHOLD and current_aroon_down < AROON_LOWER_THRESHOLD            strong_down = current_aroon_down > AROON_UPPER_THRESHOLD and current_aroon_up < AROON_LOWER_THRESHOLD
                # ===== 交易决策 =====            if position == 0:  # 空仓状态                # 多头信号                if aroon_cross_up or strong_up:                    position = POSITION_SIZE                    entry_price = current_price                    target_pos.set_target_volume(position)                    signal_type = "交叉" if aroon_cross_up else "强势"                    trades.append({                        'type''开多',                        'time': current_time,                        'price': current_price,                        'signal': signal_type                    })                    print(f"开多仓: {current_time}, 价格: {current_price:.2f}, 信号: Aroon {signal_type}")
                    # 空头信号                elif aroon_cross_down or strong_down:                    position = -POSITION_SIZE                    entry_price = current_price                    target_pos.set_target_volume(position)                    signal_type = "交叉" if aroon_cross_down else "强势"                    trades.append({                        'type''开空',                        'time': current_time,                        'price': current_price,                        'signal': signal_type                    })                    print(f"开空仓: {current_time}, 价格: {current_price:.2f}, 信号: Aroon {signal_type}")
                elif position > 0:  # 持有多头                # 平多信号                if aroon_cross_down:                    profit_pct = (current_price / entry_price - 1) * 100                    target_pos.set_target_volume(0)                    trades.append({                        'type''平多',                        'time': current_time,                        'price': current_price,                        'profit_pct': profit_pct                    })                    print(f"平多仓: {current_time}, 价格: {current_price:.2f}, 盈亏: {profit_pct:.2f}%")                    position = 0                    entry_price = 0
                elif position 0:  # 持有空头                # 平空信号                if aroon_cross_up:                    profit_pct = (entry_price / current_price - 1) * 100                    target_pos.set_target_volume(0)                     trades.append({                        'type''平空',                        'time': current_time,                        'price': current_price,                        'profit_pct': profit_pct                    })                    print(f"平空仓: {current_time}, 价格: {current_price:.2f}, 盈亏: {profit_pct:.2f}%")                    position = 0                    entry_price = 0
    except BacktestFinished as e:    print("回测结束")    api.close()
    今天代码所在的位置:
    代码已经提交:

    代码和数据下载:AI量化实验室——2025量化投资的星辰大海

    AI量化实验室 星球,已经运行三年多,1700+会员。

    aitrader代码,因子表达式引擎、遗传算法(Deap)因子挖掘引等,支持vnpy,qlib,backtrader和bt引擎,内置多个年化30%+的策略,每周五迭代一次,代码和数据在星球全部开源。

    点击 “查看原文”,直接访问策略集合

    扩展  •  历史文章   

    EarnMore(赚得更多)基于RL的投资组合管理框架:一致的股票表示,可定制股票池管理。(附论文+代码)

    机器学习驱动的策略开发通过流程 | 普通人阶层跃迁的可能路径?

    年化30.24%,最大回撤19%,综合动量多因子评分策略再升级(python代码+数据)

    三秒钟创建一个年化28%,夏普比1.25的策略(python系统已开放源代码下载)

    6年年化收益46%,最大回撤率为16%的策略(附python代码)

    Python社区是高质量的Python/Django开发社区
    本文地址:http://www.python88.com/topic/185589
     
    51 次点击