3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
**AR(人气指标)和BR(意愿指标)**是量化交易中非常经典的交易情绪指标。AR 衡量市场的买卖人气,BR 衡量市场的买卖意愿。当 AR 和 BR 指标同时处于低位(如低于 60)并开始拐头向上时,通常意味着市场情绪极度悲观后的反弹契机(超卖抄底信号);而当指标高于 150 时,则意味着市场过热,是获利了结的信号。
在聚宽(JoinQuant)平台中,我们可以直接通过聚宽因子库获取 AR 和 BR 因子,或者通过 jqlib.technical_analysis 库进行计算。以下是完整的策略设计与 Python 源码实现。
get_factor_values 获取过去 3 个交易日的 AR 和 BR 因子值。# 导入聚宽函数库
import jqdata
from jqfactor import get_factor_values
import pandas as pd
import numpy as np
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 股票类交易手续费设置
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# 每天 09:30 运行策略
run_daily(market_open, time='09:30')
def market_open(context):
# 获取沪深300成分股
stocks = get_index_stocks('000300.XSHG')
# 获取当前逻辑日期的前一天
yesterday = context.previous_date
# 获取过去 3 个交易日的 AR 和 BR 因子值(用于判断拐头)
factor_data = get_factor_values(
securities=stocks,
factors=['AR', 'BR'],
end_date=yesterday,
count=3
)
df_ar = factor_data['AR']
df_br = factor_data['BR']
# 排除停牌或无因子数据的股票
current_data = get_current_data()
# 1. 卖出逻辑:持仓股票中,AR 或 BR 高于 150 的进行卖出
for stock in list(context.portfolio.positions.keys()):
if stock in df_ar.columns and stock in df_br.columns:
# 获取最新的因子值(即昨日值)
latest_ar = df_ar[stock].iloc[-1]
latest_br = df_br[stock].iloc[-1]
if latest_ar > 150 or latest_br > 150:
order_target(stock, 0)
log.info(f"[卖出] 股票 {stock} 情绪过热,AR={latest_ar:.2f}, BR={latest_br:.2f},执行卖出。")
# 2. 买入逻辑筛选
buy_list = []
for stock in stocks:
# 过滤停牌股票
if current_data[stock].paused:
continue
if stock in df_ar.columns and stock in df_br.columns:
ar_series = df_ar[stock].dropna()
br_series = df_br[stock].dropna()
# 确保有足够的数据计算拐头(至少3天)
if len(ar_series) < 3 or len(br_series) < 3:
continue
# 获取最近三天的值:t-2, t-1, t (t为昨日)
ar_t2, ar_t1, ar_t = ar_series.iloc[-3], ar_series.iloc[-2], ar_series.iloc[-1]
br_t2, br_t1, br_t = br_series.iloc[-3], br_series.iloc[-2], br_series.iloc[-1]
# 条件1:AR 和 BR 均低于 60
condition_low = (ar_t < 60) and (br_t < 60) and (ar_t1 < 60) and (br_t1 < 60)
# 条件2:同步拐头向上 (今日值 > 昨日值)
condition_turn_up = (ar_t > ar_t1) and (br_t > br_t1)
if condition_low and condition_turn_up:
buy_list.append(stock)
# 3. 执行买入:等权重分配可用资金
if buy_list:
cash = context.portfolio.available_cash
# 限制单日最大买入数量,避免资金过度分散
max_buy = min(len(buy_list), 5)
target_buy_list = buy_list[:max_buy]
value_per_stock = cash / max_buy
for stock in target_buy_list:
if context.portfolio.positions[stock].total_amount == 0:
order_value(stock, value_per_stock)
log.info(f"[买入] 股票 {stock} 触发抄底信号,ARBR 低位拐头向上,买入金额:{value_per_stock:.2f}元。")
09:30 运行,获取因子数据时,end_date 设为 context.previous_date(昨日),确保只使用历史已披露的财务与交易数据,完全规避了未来函数。get_factor_values 获取 count=3 的数据,对比 iloc[-1](最新值)与 iloc[-2](前一日值),当最新值大于前一日值时,即判定为“拐头向上”。set_option('use_real_price', True) 真实价格模式,使回测与模拟盘的撮合机制更贴近实盘。