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

from tqsdk import TqApi, TqAuth, TqBacktest, TargetPosTask, BacktestFinished
import pandas as pd
from datetime import date
from tqsdk import TqApi, TqAuth,TqBacktest,TargetPosTask
import pandas as pd
from datetime import date
import os
def 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 default
username = get_env_var('TQ_USERNAME')
password = get_env_var('TQ_PASSWORD')
SYMBOL = "SHFE.au2306"
POSITION_SIZE = 30
START_DATE = date(2023, 2, 20)
END_DATE = date(2023, 5, 5)
AROON_PERIOD = 10
AROON_UPPER_THRESHOLD = 75
AROON_LOWER_THRESHOLD = 25
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 = TqApi(backtest=TqBacktest(start_dt=START_DATE, end_dt=END_DATE),
auth=TqAuth(username, password))
klines = api.get_kline_serial(SYMBOL, 60 * 60 * 24)
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
klines['rolling_high'] = klines['high'].rolling(window=AROON_PERIOD).max()
klines['rolling_low'] = klines['low'].rolling(window=AROON_PERIOD).min()
aroon_up = []
aroon_down = []
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]
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)
klines['aroon_up'] = aroon_up
klines['aroon_down'] = aroon_down
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
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
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%+的策略,每周五迭代一次,代码和数据在星球全部开源。
点击 “查看原文”,直接访问策略集合。