3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在聚宽(JoinQuant)平台中,计算全市场上涨和下跌家数(通常称为市场广度指标)的核心逻辑是:获取全市场所有股票列表,通过 get_current_data() 获取当天的行情快照,比较最新价(last_price)与前收盘价(pre_close)。
以下是具体的实现代码和详细说明。
get_all_securities(['stock']) 获取全市场股票代码。get_current_data() 获取当前的停牌状态、最新价和前收盘价。paused == True)。last_price > pre_closelast_price < pre_closelast_price == pre_close# -*- coding: utf-8 -*-
from jqdata import *
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 过滤掉order系列API产生的比error级别低的log
log.set_level('order', 'error')
# 设定定时运行,例如每天收盘前10分钟计算一次
run_daily(calc_market_breadth, '14:50')
def calc_market_breadth(context):
"""
计算全市场涨跌家数
"""
# 1. 获取当前交易日上市的所有股票代码
# date参数确保只获取当时还在上市的股票
all_securities = get_all_securities(['stock'], date=context.current_dt)
stock_list = list(all_securities.index)
# 2. 获取当前时刻的行情快照数据
# get_current_data 返回一个 dict,key 是股票代码,value 是对象
current_data = get_current_data()
# 初始化计数器
up_count = 0 # 上涨家数
down_count = 0 # 下跌家数
flat_count = 0 # 平盘家数
paused_count = 0 # 停牌家数
# 3. 遍历统计
for code in stock_list:
# 获取该股票的数据对象
data = current_data[code]
# 如果股票停牌,通常不计入涨跌统计,或者单独统计
if data.paused:
paused_count += 1
continue
# 获取最新价和前收盘价
# 注意:在回测中,last_price 在盘中代表当前分钟收盘价,收盘后代表当日收盘价
price = data.last_price
pre_close = data.pre_close
# 比较价格
if price > pre_close:
up_count += 1
elif price < pre_close:
down_count += 1
else:
flat_count += 1
# 4. 打印或记录结果
log.info("=== 市场广度统计 (%s) ===" % context.current_dt)
log.info("上涨家数: %d" % up_count)
log.info("下跌家数: %d" % down_count)
log.info("平盘家数: %d" % flat_count)
log.info("停牌家数: %d" % paused_count)
# 可以在回测图表中画出曲线
record(up_count=up_count, down_count=down_count)
# 5. (可选) 计算涨跌比 ADL 或 涨跌家数差
# diff = up_count - down_count
# ratio = up_count / down_count if down_count > 0 else 0
get_all_securities: 必须传入 date=context.current_dt,这样可以确保获取的是回测当时实际上市的股票列表,自动剔除已退市或未上市的股票,避免未来函数。get_current_data: 这是回测和模拟交易中获取“当前切片数据”最高效的API。它包含了 last_price(最新价)、pre_close(昨收价)和 paused(是否停牌)等关键字段。if data.paused: 剔除了停牌股票。在实际的市场情绪分析中,停牌股票通常不具备参考意义,因此将其排除。for 循环处理 4000+ 只股票在回测中速度尚可,但如果策略逻辑非常复杂,建议尽量减少循环内部的计算量。Q: 为什么使用 last_price 而不是 close?
A: get_current_data() 返回的对象属性中,last_price 代表最新成交价。在盘中运行时(例如 10:00 运行),它代表 10:00 的价格;在收盘后运行时,它代表收盘价。这比使用 history 获取数据更符合“当前状态”的语义。
Q: 如何计算涨停和跌停家数?
A: get_current_data() 的返回对象中包含 high_limit(涨停价)和 low_limit(跌停价)。可以在循环中增加判断:
data.last_price >= data.high_limitdata.last_price <= data.low_limitQ: 这个指标可以用来做什么?
A: 涨跌家数是衡量市场情绪的重要指标。