Files
simonandClaude Opus 4.7 271a9343a5 Initial commit: cc-cursor 全链路量化研究平台
7 Sprints 全部完成:
  Sprint 0: 基础设施 (DataManager + MariaDB)
  Sprint 1: 因子引擎 (34因子/12分类)
  Sprint 2: VectorBT 回测 (5策略+截面)
  Sprint 3: Optuna 优化 (+Walk-Forward)
  Sprint 4: ML 模型 (LightGBM+CatBoost)
  Sprint 5: Qwen 情绪因子 (三源新闻+日期对齐)
  Sprint 6: Agent 系统 (4Agent+日报.md/.html)

生产加固 (15项): Tushare双源fallback, SSH自动恢复, pool_pre_ping,
  save_daily先删后插, load_dotenv绝对路径, 日报5d/20d修复,
  RiskAgent改上证指数, 昨日对比+数据截止, mac_report utf8mb4,
  CLAUDE-*.md 9条已知Bug, demo全参数化, djapi数据源归一化,
  indexDatas API修正

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-07 15:59:05 +08:00

145 lines
5.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pandas as pd
# 导入当站目录的config文件
try:
# 尝试相对导入(作为包的一部分)
from .config import TS_TOKEN, START_DATE, END_DATE, PRECISION_CONFIG
from .stock_utils import *
except (ImportError, SystemError):
# 失败则使用绝对导入(直接运行脚本)
from config import TS_TOKEN, START_DATE, END_DATE, PRECISION_CONFIG
from stock_utils import *
from .data_source import get_tushare_pro
pro = get_tushare_pro()
def get_index_by_name(index_name: str) -> pd.DataFrame:
"""
通过指数名称查询指数基本信息(使用tushare的index_basic接口)
Args:
index_name (str): 要查询的指数名称(支持模糊匹配,如"上证")
Returns:
pd.DataFrame: 包含查询结果的DataFrame,列包括:
- ts_code: 指数代码
- name: 指数名称
- fullname: 指数全称
- market: 市场
- publisher: 发布方
- index_type: 指数类型
- etc.
Raises:
Exception: 当tushare接口调用失败时抛出异常
Example:
>>> df = get_index_by_name("上证50")
>>> print(df[['ts_code', 'name']])
"""
try:
# 调用tushare接口查询指数信息
df = pro.index_basic(name=index_name)
# 检查返回结果是否为空
if df.empty:
print(f"未找到名称包含'{index_name}'的指数")
return pd.DataFrame() # 返回空DataFrame保持类型一致
return df
except Exception as e:
print(f"查询指数信息失败: {str(e)}")
return pd.DataFrame()
def get_index_daily_data(ts_code: str, start_date: str = START_DATE, end_date: str = END_DATE) -> pd.DataFrame:
"""
通过指数代码查询日线行情数据(合并基本行情和扩展行情)
Args:
ts_code (str): 指数代码(如"000001.SH"
start_date (str): 开始日期(格式"YYYYMMDD",默认使用config中的START_DATE
end_date (str): 结束日期(格式"YYYYMMDD",默认使用config中的END_DATE
Returns:
pd.DataFrame: 合并后的日线行情数据,包含以下列(示例):
- ts_code: 指数代码
- trade_date: 交易日期
- close: 收盘点位
- open: 开盘点位
- high: 最高点位
- low: 最低点位
- pe: 市盈率
- pb: 市净率
- etc.
Raises:
Exception: 当tushare接口调用失败或数据合并失败时抛出异常
Example:
>>> df = get_index_daily_data("000001.SH")
>>> print(df[['trade_date', 'close', 'pe']].head())
"""
try:
start_date = date_format_correction(start_date)
end_date = date_format_correction(end_date)
# 1. 查询日线基本行情(核心数据,必须成功)
daily_df = pro.index_daily(
ts_code=ts_code,
start_date=start_date,
end_date=end_date,
fields="ts_code,trade_date,open,high,low,close,pre_close,change,pct_chg,vol,amount"
)
if daily_df is None or daily_df.empty:
print("未找到指数{}{}{}期间的行情数据".format(ts_code, start_date, end_date))
return pd.DataFrame()
# 2. 尝试查询扩展行情(PE/PB 等,需要高权限,失败不阻塞)
try:
daily_basic_df = pro.index_dailybasic(
ts_code=ts_code,
start_date=start_date,
end_date=end_date,
fields="ts_code,trade_date,total_mv,float_mv,pe,pe_ttm,pb,turnover_rate,turnover_rate_f"
)
if daily_basic_df is not None and not daily_basic_df.empty:
daily_df = pd.merge(
daily_df, daily_basic_df,
on=['ts_code', 'trade_date'],
how='left'
)
except Exception as e:
print("index_dailybasic 不可用(权限不足或接口变更): {}".format(e))
return daily_df
except Exception as e:
print("查询指数日线行情失败: {}".format(e))
raise # 抛出而非静默返回空,让 view 层返回错误信息
if __name__ == "__main__":
# 测试指数查询
print("测试指数查询:")
index_df = get_index_by_name("中证500")
if not index_df.empty:
print(index_df[['ts_code', 'name']].head())
else:
print("未查询到指数信息")
'''# 测试指数行情获取
print("\n测试指数日线行情:")
test_code = "000016.SH" # 上证50指数代码
daily_data = get_index_daily_data(test_code, start_date="20230101", end_date="20231231")
if not daily_data.empty:
print(f"获取到{daily_data.shape[0]}条数据")
# 显示关键列的前5行
print(daily_data[['trade_date', 'close', 'pe', 'pb']].head())
# 数据完整性检查
print("\n数据完整性检查:")
print(daily_data[['close', 'pe']].describe())
else:
print(f"未获取到指数{test_code}的行情数据")'''