🚀 AI 一键生成 joinquant 策略代码

JoinQuant 策略开发:基于 Aroon 指标的趋势捕捉系统

joinquant | 发布时间: 2025/12/24
以下内容由 EasyQuant 生成。

问题描述

请编写一个基于 Aroon 阿隆指标的趋势策略

解决方案

这是一个基于 Aroon(阿隆)指标的趋势跟踪策略。

策略原理

阿隆指标(Aroon Indicator) 由 Aroon Up(上线)和 Aroon Down(下线)两条曲线组成,用于判断趋势的方向和强度。

  1. 计算公式

    • Aroon Up = $[(N - \text{距离最高价的天数}) / N] \times 100$
    • Aroon Down = $[(N - \text{距离最低价的天数}) / N] \times 100$
    • $N$ 通常取 25 天。
  2. 交易逻辑

    • 买入信号:当 Aroon Up 大于 Aroon Down,且 Aroon Up 大于 50(表示上涨趋势强劲)时,全仓买入。
    • 卖出信号:当 Aroon Down 大于 Aroon Up(表示下跌趋势占优)时,清仓卖出。

策略代码

# -*- coding: utf-8 -*-
import jqdata
import numpy as np

def initialize(context):
    """
    初始化函数,设定基准、手续费、滑点、全局变量等
    """
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 过滤掉order系列API产生的比error级别低的log
    log.set_level('order', 'error')
    
    # 设定股票类每笔交易时的手续费
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 定义全局变量
    # 设定要操作的标的,这里以平安银行为例
    g.security = '000001.XSHE'
    
    # 阿隆指标的计算周期 N
    g.N = 25
    
    # 每天开盘时运行
    run_daily(market_open, time='open')

def market_open(context):
    """
    每日交易逻辑
    """
    security = g.security
    
    # 获取过去 N 天的最高价和最低价数据
    # 注意:我们需要包含今天的数据来判断当前的趋势,但在回测引擎中,
    # 'open'时间点调用attribute_history获取的是昨天及之前的数据(避免未来函数)。
    # 如果需要包含分钟级的实时数据,逻辑会更复杂。这里使用基于日线的收盘价逻辑(T-1数据决策,T日执行)。
    h_data = attribute_history(security, g.N, '1d', ['high', 'low'])
    
    # 如果数据长度不足(例如刚上市),则跳过
    if len(h_data) < g.N:
        return

    # 提取最高价和最低价的数组
    highs = h_data['high'].values
    lows = h_data['low'].values
    
    # 计算距离最高价和最低价的天数
    # argmax() 返回最大值的索引,索引 0 代表 N 天前,索引 N-1 代表最近一天
    # 距离天数 = (总天数 - 1) - 索引值
    days_since_high = (g.N - 1) - highs.argmax()
    days_since_low = (g.N - 1) - lows.argmin()
    
    # 计算 Aroon Up 和 Aroon Down
    aroon_up = ((g.N - days_since_high) / float(g.N)) * 100
    aroon_down = ((g.N - days_since_low) / float(g.N)) * 100
    
    # 获取当前持仓
    curr_position = context.portfolio.positions[security].total_amount
    available_cash = context.portfolio.available_cash
    
    # --- 交易信号判断 ---
    
    # 买入条件:Aroon Up > Aroon Down 且 Aroon Up > 50 (趋势向上且强度足够)
    if aroon_up > aroon_down and aroon_up > 50:
        if curr_position == 0:
            # 全仓买入
            order_value(security, available_cash)
            log.info("买入信号触发: Aroon Up(%.2f) > Aroon Down(%.2f)" % (aroon_up, aroon_down))
            
    # 卖出条件:Aroon Down > Aroon Up (趋势转跌)
    elif aroon_down > aroon_up:
        if curr_position > 0:
            # 清仓卖出
            order_target(security, 0)
            log.info("卖出信号触发: Aroon Down(%.2f) > Aroon Up(%.2f)" % (aroon_down, aroon_up))
            
    # 记录指标值,可以在回测图表中查看
    record(Aroon_Up=aroon_up, Aroon_Down=aroon_down)

Q&A

Q1: 为什么代码中计算 days_since_high 使用了 (g.N - 1) - highs.argmax()
A1: attribute_history 返回的数据是按时间顺序排列的数组。假设 g.N=25,数组索引范围是 0 到 24。索引 24 代表最近的一天(昨天)。如果最高价出现在索引 24,说明距离最高价的天数是 0 天。公式 (25 - 1) - 24 = 0 正好符合定义。

Q2: 这个策略适合什么类型的市场?
A2: Aroon 是一个典型的趋势指标。它在单边上涨或下跌的趋势行情中表现较好,但在震荡市(Aroon Up 和 Aroon Down 都在 50 以下纠缠时)容易产生频繁的买卖信号,导致磨损。

Q3: 如何修改策略以操作多只股票?
A3: 可以将 g.security 修改为一个列表(例如 get_index_stocks('000300.XSHG')),然后在 market_open 函数中使用 for 循环遍历这个列表,对每只股票分别计算指标和下单。同时需要注意资金分配(例如每只股票分配总资金的 1/10)。