3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个计算沪深300指数腾落指标(ADL)的 QMT Python 策略脚本。
腾落指标 (ADL - Advance-Decline Line) 是一种市场广度指标,用于衡量参与市场涨跌的股票数量。
init 中初始化 ADL 累加器。handlebar 中,获取当前 K 线时间点的沪深300成分股。paint 函数在副图绘制曲线。# -*- coding: gbk -*-
import pandas as pd
def init(ContextInfo):
"""
初始化函数
"""
# 定义目标指数代码:沪深300
ContextInfo.index_code = '000300.SH'
# 初始化 ADL 累积值,从0开始
ContextInfo.adl_value = 0
# 设置副图显示的指标名称和颜色
# 注意:paint函数会自动处理绘图,这里主要用于逻辑初始化
def handlebar(ContextInfo):
"""
K线周期运行函数
"""
# 获取当前K线的位置
barpos = ContextInfo.barpos
# 获取当前K线的时间戳(毫秒)
timetag = ContextInfo.get_bar_timetag(barpos)
# 1. 获取该时间点沪深300的成分股列表
# 注意:使用 timetag 可以获取历史时刻真实的成分股,避免幸存者偏差
stock_list = ContextInfo.get_sector(ContextInfo.index_code, timetag)
if not stock_list:
return
# 2. 批量获取成分股的行情数据
# 我们需要比较今日收盘价和昨日收盘价,所以 count=2
# period='1d' 表示日线,dividend_type='front' 使用前复权价格
data_map = ContextInfo.get_market_data_ex(
fields=['close'],
stock_code=stock_list,
period='1d',
count=2,
dividend_type='front',
fill_data=True, # 填充停牌数据
subscribe=False
)
up_count = 0 # 上涨家数
down_count = 0 # 下跌家数
# 3. 遍历所有成分股计算涨跌
for stock in stock_list:
if stock in data_map:
df = data_map[stock]
# 确保有足够的数据进行比较(至少需要两天的数据)
if len(df) >= 2:
# 获取今日收盘价和昨日收盘价
# iloc[-1] 是最新一根K线(当前bar),iloc[-2] 是前一根
close_today = df.iloc[-1]['close']
close_prev = df.iloc[-2]['close']
# 判断涨跌
if close_today > close_prev:
up_count += 1
elif close_today < close_prev:
down_count += 1
# 平盘(close_today == close_prev)不计入
# 4. 计算当期净腾落值
net_change = up_count - down_count
# 5. 累加到 ADL
# 注意:如果是第一根K线,ADL就是当天的净值,之后累加
ContextInfo.adl_value += net_change
# 6. 绘图输出
# 在副图绘制 ADL 指标线
ContextInfo.paint('ADL', ContextInfo.adl_value, -1, 0, 'yellow')
# 可选:绘制一条0轴参考线
ContextInfo.paint('Zero', 0, -1, 0, 'gray', 'noaxis')
运行模式:
数据准备:
get_market_data_ex 可能无法获取足够的历史价格,导致计算结果为 0。显示位置:
逻辑解释:
ContextInfo.get_sector(..., timetag):这是关键步骤。它确保了在回测历史时间点(比如2020年)时,使用的是当时(2020年)的沪深300成分股,而不是现在的成分股,从而保证了回测的准确性。count=2:我们需要“今天”和“昨天”的数据来判断涨跌,所以一次性取2根K线。Q: 为什么 ADL 曲线的数值很大或者是负数?
A: ADL 是一个累积指标,其绝对数值的大小取决于计算的起始时间点。绝对值本身没有意义,有意义的是曲线的走势和形态(例如与指数价格的背离)。
Q: 为什么第一根 K 线的 ADL 值不是 0?
A: 脚本逻辑是 ContextInfo.adl_value += net_change。在图表的第一根 K 线,它会计算当天的 (涨-跌),所以值是当天的净变化量,不一定是 0。
Q: 如何计算其他指数(如中证500)的 ADL?
A: 只需将 init 函数中的 ContextInfo.index_code = '000300.SH' 修改为 '000905.SH' (中证500) 或其他指数代码即可。