一句话回答: BRAR 由 AR(人气指标) 和 BR(意愿指标) 两条线组成:AR 用「最高价−开盘」与「开盘−最低价」的强弱比衡量当日多空人气;BR 用「最高价−昨收」与「昨收−最低价」衡量相对昨收的买卖意愿。用 AlphaFeed 取回前复权日线后,几行 pandas 就能算出 AR、BR,判断情绪过热或低迷,不需要 TA-Lib。
为什么会有这个问题 / 传统做法的痛点
价格指标看趋势,但看不出「情绪」。BRAR 从每日 K 线的开高低收结构里提取买卖意愿:AR 反映以开盘价为基准的多空争夺,BR 反映以昨收为基准的追涨杀跌意愿。坑在于:一是要用前复权价,否则除权日结构失真;二是 AR/BR 有各自的经验区间,需要成对看、看背离,而不是单看一条。
分步骤解决(每步配可运行代码)
第 1 步:取前复权日线
python
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
df = af.klines.get("600519.SH", period="1d", count=250,
adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)
BRAR 依赖开高低收结构,务必用
adjust="forward"(前复权),避免除权跳空。
第 2 步:计算 AR 与 BR
python
def brar(df: pd.DataFrame, n: int = 26):
high, low, open_, close = df["high"], df["low"], df["open"], df["close"]
prev_close = close.shift(1)
# AR:以开盘价为基准的人气
ar = (high - open_).rolling(n).sum() / (open_ - low).rolling(n).sum() * 100
# BR:以昨收为基准的意愿(负值截断为 0)
up = (high - prev_close).clip(lower=0)
dn = (prev_close - low).clip(lower=0)
br = up.rolling(n).sum() / dn.rolling(n).sum() * 100
return ar, br
df["AR"], df["BR"] = brar(df, n=26)
print(df[["trade_date", "close", "AR", "BR"]].tail(5).to_string(index=False))
参数与含义:
| 字段 | 公式要点 | 解读 |
|---|---|---|
n |
统计周期 | 常用 26 |
AR |
Σ(高−开) ÷ Σ(开−低) ×100 | 人气:高=活跃/过热 |
BR |
Σ(高−昨收)⁺ ÷ Σ(昨收−低)⁺ ×100 | 意愿:追涨杀跌强弱 |
第 3 步:经验区间与信号
python
ar, br = df["AR"].iloc[-1], df["BR"].iloc[-1]
def ar_state(x):
if x >= 180: return "AR 过热(警惕回落)"
if x <= 50: return "AR 低迷(可能筑底)"
return "AR 正常"
print(f"AR={ar:.0f} → {ar_state(ar)} | BR={br:.0f}")
# 经验:BR 高于 AR 且 BR 快速冲高常见于情绪亢奋;BR 低于 100 且低于 AR 常见于低迷
AR/BR 经验区间(参考,因品种而异):
| 指标 | 低迷 | 正常 | 过热 |
|---|---|---|---|
| AR | < 50 | 80~150 | > 180 |
| BR | < 50 | 70~150 | > 300 |
第 4 步:批量筛「AR 低位」候选
python
codes = ["600519.SH", "000001.SZ", "601318.SH", "000858.SZ", "300750.SZ"]
data = af.klines.batch(codes, period="1d", count=60,
adjust="forward", to_dataframe=True)
low_ar = []
for sym, k in data.items():
k = k.sort_values("trade_date")
ar, br = brar(k)
if pd.notna(ar.iloc[-1]) and ar.iloc[-1] <= 70:
low_ar.append((sym, round(float(ar.iloc[-1]), 0)))
print("AR 低位候选:", low_ar)
关键坑与注意事项
- 必须用前复权价:除权日开高低收结构错位会让 AR/BR 失真。
- AR、BR 要成对看:单看一条意义有限;常看二者的相对高低与背离(如 BR 远高于 AR)。
- BR 计算要截断负值 :
(high−prev_close)和(prev_close−low)取非负部分再求和,别直接相减。 - 阈值是经验值:不同市场阶段/品种区间不同,作相对参考而非绝对买卖点。
- 除以零风险:区间内分母趋近 0(如持续一字板)会让指标异常,需处理异常值。
- 样本足够 :
n=26需预热,count建议 ≥ 40,忽略头部 NaN。
常见问题(FAQ)
Q:AR 和 BR 有什么区别?
A:AR 以当日开盘价 为基准衡量人气;BR 以昨日收盘价为基准衡量意愿。AR 看盘中多空争夺,BR 看相对昨收的追涨杀跌。
Q:BR 为什么要对负值截断?
A:BR 只累计「高于昨收的强度」和「低于昨收的弱度」,所以 (high−prev_close) 与 (prev_close−low) 取非负部分,避免负值互相抵消。
Q:默认周期用多少?
A:常用 26。周期越短越灵敏。先用 26 观察 AR/BR 的相对关系。
Q:需要付费吗?
A:单只历史日线有免费额度;全市场批量算 BRAR(klines.batch + universes)需 Starter 及以上。详见定价页。
小结
BRAR 情绪指标的本质是从每日 K 线结构里提取买卖意愿:AR 以开盘为基准看人气、BR 以昨收为基准看意愿。实现只需 pandas,不依赖 TA-Lib。关键是用前复权价、BR 负值截断、成对看 AR/BR 及其背离、把阈值当相对参考。用 AlphaFeed 取回前复权日线,几行就能算出 AR/BR 并做全市场筛选。
参考
- AlphaFeed Python SDK 文档:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
- AlphaFeed 官网:https://alphafeed.org/