在聚宽平台编写回测交易代码时,发现日志中不断报错“证券代码错误:……”,但是无论如何调试,都无法找出错误,初步判断是在获取股票数据时出现了错误,但是具体原因和解决方法就不得而知了,还请大家帮忙寻找错误并加以修正,谢谢!
原代码(含对股票数据获取的调试内容但可能是调试代码有误):
from jqdata import *
import datetime
import pandas as pd
# 全局变量
g = {
'stock_weights': {}, # 存储股票权重
'start_date': datetime.date(2023, 4, 5), # 设定开始日期
}
# 获取指定日期后上市的次新股
def get_subnew_stocks(start_date):
if not isinstance(start_date, datetime.date):
raise ValueError('start_date must be a datetime.date object')
# 获取所有股票信息
stocks = get_all_securities(types=['stock'])
# 过滤出指定日期及以后上市的股票
subnew_stocks = stocks[stocks['start_date'] >= start_date]
# 返回次新股的股票代码列表
return subnew_stocks.index.tolist()
# 初始化函数,设置基准和调度
def initialize(context):
set_benchmark('000300.XSHG') # 设置基准为沪深300指数
set_option('use_real_price', True) # 开启动态复权模式
run_daily(compute_index, time='before_open') # 开盘前运行compute_index函数
# 开盘前运行的函数
def before_trading_start(context):
pass # 可以在这里添加开盘前需要执行的代码
# 每天开盘前运行的函数,计算次新股权重并存储结果
def compute_index(context):
# 获取次新股股票列表
subnew_stocks = get_subnew_stocks(g['start_date'])
# 如果次新股列表为空,则打印信息并返回
if not subnew_stocks:
print("没有找到符合条件的次新股")
return
# 构建查询条件,获取股票的流通市值、换手率
q = query(valuation.code, valuation.market_cap, valuation.turnover_ratio).filter(valuation.code.in_(subnew_stocks))
# 使用当前回测或实盘日期获取基本面数据
current_date = context.current_dt.date()
df = get_fundamentals(q, date=current_date)
# 如果基本面数据为空,则打印信息并返回
if df.empty:
print("基本面查询结果为空")
return
# 获取每只股票的当日收盘价和涨跌幅
valid_stocks = {} # 用于存储有效的股票数据
total_pct_change = 0.0 # 用于计算涨跌幅总和
for stock in subnew_stocks:
try:
daily_data = get_price(stock, end_date=current_date, frequency='daily', fields=['close', 'pre_close'])
# 调试:检查数据的格式和内容
if not isinstance(daily_data, pd.DataFrame):
print(f"股票 {stock} 的数据不是pandas DataFrame格式")
continue
if 'close' not in daily_data.columns or 'pre_close' not in daily_data.columns:
print(f"股票 {stock} 的数据中没有包含'close'或'pre_close'字段")
continue
if daily_data['close'].empty or daily_data['pre_close'].empty:
print(f"股票 {stock} 的收盘价或前收盘价数据为空")
continue
close_price = daily_data['close'][0]
pre_close_price = daily_data['pre_close'][0]
# 调试:检查价格是否为数字
if not (isinstance(close_price, (int, float)) and isinstance(pre_close_price, (int, float))):
print(f"股票 {stock} 的收盘价或前收盘价不是数字")
continue
pct_change = (close_price - pre_close_price) / pre_close_price
valid_stocks[stock] = pct_change
total_pct_change += pct_change
except Exception as e:
print(f"Error getting price data for stock {stock}: {e}")
continue
if not valid_stocks:
print("没有获取到有效的股票价格数据")
return
for stock, pct_change in valid_stocks.items():
g['stock_weights'][stock] = pct_change / total_pct_change
# 交易时运行的函数
def handle_data(context, data):
total_value = context.portfolio.total_value
for stock, weight in g['stock_weights'].items():
value_per_stock = total_value * weight
if stock not in data:
print(f"证券代码错误: {stock}")
continue
order_target_value(stock, value_per_stock)
日志报错:
2023-04-07 09:30:00 - INFO - 证券代码错误: 001239.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001282.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001286.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001287.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001306.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001324.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001326.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001328.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001358.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001360.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001367.XSHE
2023-04-07 09:30:00 - INFO - 证券代码错误: 001373.XSHE

上图为日志报错内容