From 21bbc9cd1e3d1e550bc952ea291fbf5de08ffbf0 Mon Sep 17 00:00:00 2001 From: hubian <908234780@qq.com> Date: Tue, 14 Apr 2026 09:29:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=AF=8F=E6=97=A5?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=8B=89=E5=8F=96=EF=BC=8C=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E6=8C=89=E6=97=A5=E6=9C=9F=E6=89=B9=E9=87=8F=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cron_daily_fetch.py | 224 +++ data/completed_stocks.txt | 2749 +++++++++++++++++++++++++++++++++++++ fetch_daily_update.py | 264 ++++ fetch_history.py | 97 +- 4 files changed, 3323 insertions(+), 11 deletions(-) create mode 100644 cron_daily_fetch.py create mode 100644 data/completed_stocks.txt create mode 100644 fetch_daily_update.py diff --git a/cron_daily_fetch.py b/cron_daily_fetch.py new file mode 100644 index 0000000..0e18497 --- /dev/null +++ b/cron_daily_fetch.py @@ -0,0 +1,224 @@ +""" +A股每日数据自动拉取脚本 (Cron专用) +每个交易日17:00自动运行,拉取当日所有股票数据 + +优化版本: +- 使用 trade_date 参数一次性获取当天所有股票数据 +- 大幅减少 API 请求次数(从 5000+ 次减少到每天 1 次) + +用法: +python3 cron_daily_fetch.py # 获取今日数据 +python3 cron_daily_fetch.py --days 5 # 获取最近5天数据 +python3 cron_daily_fetch.py --date 20260408 # 获取指定日期数据 + +Cron配置: +0 17 * * 1-5 python3 /home/xian/.openclaw/common/stock_system/cron_daily_fetch.py +""" + +import tushare as ts +import pandas as pd +import os +import time +from datetime import datetime, timedelta +from pathlib import Path +import argparse + +# 配置 +BASE_DIR = Path(__file__).parent +DATA_DIR = BASE_DIR / 'data' +DB_FILE = DATA_DIR / 'progress.db' +LOG_FILE = BASE_DIR / 'logs' / 'daily_fetch.log' +MAIN_FILE = DATA_DIR / 'stock_daily_data.parquet' + +REQUEST_INTERVAL = 0.5 # 每次请求间隔(按日期获取次数少,可以慢一点也没关系) + + +def log(msg): + """写入日志""" + timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + log_msg = f"[{timestamp}] {msg}" + print(log_msg) + + LOG_FILE.parent.mkdir(exist_ok=True) + with open(LOG_FILE, 'a') as f: + f.write(log_msg + '\n') + + +def setup_tushare(): + """初始化tushare""" + token = os.environ.get('TUSHARE_TOKEN', '') + if not token: + config_file = BASE_DIR / 'config.txt' + if config_file.exists(): + token = config_file.read_text().strip() + if not token: + raise ValueError("缺少 Tushare Token") + ts.set_token(token) + return ts.pro_api() + + +def is_weekday(date_str): + """判断是否为工作日(周一到周五)""" + d = datetime.strptime(date_str, '%Y%m%d') + return d.weekday() < 5 + + +def get_trade_dates_in_range(start_date, end_date): + """获取日期范围内的所有工作日""" + start = datetime.strptime(start_date, '%Y%m%d') + end = datetime.strptime(end_date, '%Y%m%d') + + trade_dates = [] + current = start + while current <= end: + if current.weekday() < 5: # 周一到周五 + trade_dates.append(current.strftime('%Y%m%d')) + current += timedelta(days=1) + + return trade_dates + + +def get_latest_trade_date(): + """获取数据中最新的交易日期""" + if not MAIN_FILE.exists(): + return None + + df = pd.read_parquet(MAIN_FILE) + if len(df) == 0: + return None + + return df['trade_date'].max() + + +def fetch_data_by_date(pro, trade_date): + """ + 按日期获取当日所有股票数据 + 这是优化版本:一次请求获取当天所有股票 + """ + log(f"获取 {trade_date} 的数据...") + + try: + # 一次性获取当天所有股票数据 + df = pro.daily(trade_date=trade_date) + + if df is None or len(df) == 0: + log(f" {trade_date} 无数据(可能是非交易日)") + return 0, None + + log(f" {trade_date} 获取到 {len(df)} 条记录") + return len(df), df + + except Exception as e: + log(f" {trade_date} 获取失败: {str(e)[:100]}") + return 0, None + + +def merge_data(new_df): + """合并新数据到主文件""" + if new_df is None or len(new_df) == 0: + return + + if MAIN_FILE.exists(): + existing_df = pd.read_parquet(MAIN_FILE) + # 合并并去重 + combined = pd.concat([existing_df, new_df], ignore_index=True) + combined = combined.sort_values(['ts_code', 'trade_date']).reset_index(drop=True) + combined = combined.drop_duplicates(subset=['ts_code', 'trade_date'], keep='last') + else: + combined = new_df + + combined.to_parquet(MAIN_FILE, index=False, compression='snappy') + return len(combined) + + +def fetch_dates(pro, dates): + """获取多个日期的数据""" + if not dates: + log("没有需要获取的日期") + return 0 + + total_new = 0 + all_new_data = [] + + log(f"需要获取 {len(dates)} 个交易日的数据") + + for i, trade_date in enumerate(dates): + count, df = fetch_data_by_date(pro, trade_date) + + if df is not None and len(df) > 0: + all_new_data.append(df) + total_new += count + + # 间隔 + if i < len(dates) - 1: + time.sleep(REQUEST_INTERVAL) + + # 一次性合并所有数据 + if all_new_data: + combined_new = pd.concat(all_new_data, ignore_index=True) + total_records = merge_data(combined_new) + log(f"数据合并完成,总记录数: {total_records}") + + return total_new + + +def main(): + """主函数""" + parser = argparse.ArgumentParser(description='A股每日数据拉取(按日期批量获取)') + parser.add_argument('--date', type=str, help='获取指定日期数据 (格式: 20260408)') + parser.add_argument('--days', type=int, default=0, help='获取最近N天数据') + args = parser.parse_args() + + log("=" * 60) + log(f"A股每日数据拉取开始") + log("=" * 60) + + try: + # 初始化 + pro = setup_tushare() + + # 确定要获取的日期 + if args.date: + # 指定日期 + dates = [args.date] + log(f"模式: 获取指定日期 {args.date}") + elif args.days > 0: + # 最近N天 + end_date = datetime.now().strftime('%Y%m%d') + start_date = (datetime.now() - timedelta(days=args.days-1)).strftime('%Y%m%d') + dates = get_trade_dates_in_range(start_date, end_date) + log(f"模式: 获取最近 {args.days} 天数据 ({start_date} ~ {end_date})") + log(f"工作日: {dates}") + else: + # 默认:获取今日数据 + today = datetime.now().strftime('%Y%m%d') + + # 如果不是工作日,跳过 + if not is_weekday(today): + log(f"今天({datetime.now().strftime('%A')})不是工作日,跳过") + return + + dates = [today] + log(f"模式: 获取今日数据 ({today})") + + # 获取数据 + new_records = fetch_dates(pro, dates) + + # 显示文件信息 + if MAIN_FILE.exists(): + size_mb = MAIN_FILE.stat().st_size / 1024 / 1024 + log(f"数据文件大小: {size_mb:.2f} MB") + + log(f"本次新增数据: {new_records} 条") + log("=" * 60) + log("完成") + + except Exception as e: + log(f"错误: {e}") + import traceback + log(traceback.format_exc()) + raise + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/data/completed_stocks.txt b/data/completed_stocks.txt new file mode 100644 index 0000000..961eb44 --- /dev/null +++ b/data/completed_stocks.txt @@ -0,0 +1,2749 @@ +000001.SZ +000002.SZ +000004.SZ +000006.SZ +000007.SZ +000008.SZ +000009.SZ +000010.SZ +000011.SZ +000012.SZ +000014.SZ +000016.SZ +000017.SZ +000019.SZ +000020.SZ +000021.SZ +000025.SZ +000026.SZ +000027.SZ +000028.SZ +000029.SZ +000030.SZ +000031.SZ +000032.SZ +000034.SZ +000035.SZ +000036.SZ +000037.SZ +000039.SZ +000042.SZ +000045.SZ +000048.SZ +000049.SZ +000050.SZ +000055.SZ +000056.SZ +000058.SZ +000059.SZ +000060.SZ +000061.SZ +000062.SZ +000063.SZ +000065.SZ +000066.SZ +000068.SZ +000069.SZ +000070.SZ +000078.SZ +000088.SZ +000089.SZ +000090.SZ +000096.SZ +000099.SZ +000100.SZ +000151.SZ +000153.SZ +000155.SZ +000156.SZ +000157.SZ +000158.SZ +000159.SZ +000166.SZ +000301.SZ +000333.SZ +000338.SZ +000400.SZ +000401.SZ +000402.SZ +000403.SZ +000404.SZ +000407.SZ +000408.SZ +000409.SZ +000410.SZ +000411.SZ +000415.SZ +000417.SZ +000419.SZ +000420.SZ +000421.SZ +000422.SZ +000423.SZ +000425.SZ +000426.SZ +000428.SZ +000429.SZ +000430.SZ +000488.SZ +000498.SZ +000501.SZ +000503.SZ +000504.SZ +000505.SZ +000506.SZ +000507.SZ +000509.SZ +000510.SZ +000513.SZ +000514.SZ +000516.SZ +000517.SZ +000518.SZ +000519.SZ +000520.SZ +000521.SZ +000523.SZ +000524.SZ +000525.SZ +000526.SZ +000528.SZ +000529.SZ +000530.SZ +000531.SZ +000532.SZ +000533.SZ +000534.SZ +000536.SZ +000537.SZ +000538.SZ +000539.SZ +000541.SZ +000543.SZ +000544.SZ +000545.SZ +000546.SZ +000547.SZ +000548.SZ +000550.SZ +000551.SZ +000552.SZ +000553.SZ +000554.SZ +000555.SZ +000557.SZ +000558.SZ +000559.SZ +000560.SZ +000561.SZ +000563.SZ +000564.SZ +000565.SZ +000566.SZ +000567.SZ +000568.SZ +000570.SZ +000571.SZ +000572.SZ +000573.SZ +000576.SZ +000581.SZ +000582.SZ +000586.SZ +000589.SZ +000590.SZ +000591.SZ +000592.SZ +000593.SZ +000595.SZ +000596.SZ +000597.SZ +000598.SZ +000599.SZ +000600.SZ +000601.SZ +000603.SZ +000605.SZ +000607.SZ +000608.SZ +000609.SZ +000610.SZ +000612.SZ +000615.SZ +000617.SZ +000619.SZ +000620.SZ +000623.SZ +000625.SZ +000626.SZ +000628.SZ +000629.SZ +000630.SZ +000631.SZ +000632.SZ +000633.SZ +000635.SZ +000636.SZ +000637.SZ +000638.SZ +000639.SZ +000650.SZ +000651.SZ +000652.SZ +000655.SZ +000656.SZ +000657.SZ +000659.SZ +000661.SZ +000663.SZ +000665.SZ +000668.SZ +000669.SZ +000670.SZ +000672.SZ +000676.SZ +000677.SZ +000678.SZ +000679.SZ +000680.SZ +000681.SZ +000682.SZ +000683.SZ +000685.SZ +000686.SZ +000688.SZ +000690.SZ +000691.SZ +000692.SZ +000695.SZ +000697.SZ +000698.SZ +000700.SZ +000701.SZ +000702.SZ +000703.SZ +000705.SZ +000707.SZ +000708.SZ +000709.SZ +000710.SZ +000711.SZ +000712.SZ +000713.SZ +000715.SZ +000716.SZ +000717.SZ +000718.SZ +000719.SZ +000720.SZ +000721.SZ +000722.SZ +000723.SZ +000725.SZ +000726.SZ +000727.SZ +000728.SZ +000729.SZ +000731.SZ +000733.SZ +000735.SZ +000736.SZ +000737.SZ +000738.SZ +000739.SZ +000750.SZ +000751.SZ +000752.SZ +000753.SZ +000755.SZ +000756.SZ +000757.SZ +000758.SZ +000759.SZ +000761.SZ +000762.SZ +000766.SZ +000767.SZ +000768.SZ +000776.SZ +000777.SZ +000778.SZ +000779.SZ +000782.SZ +000783.SZ +000785.SZ +000786.SZ +000788.SZ +000789.SZ +000790.SZ +000791.SZ +000792.SZ +000793.SZ +000795.SZ +000796.SZ +000797.SZ +000798.SZ +000799.SZ +000800.SZ +000801.SZ +000802.SZ +000803.SZ +000807.SZ +000809.SZ +000810.SZ +000811.SZ +000812.SZ +000813.SZ +000815.SZ +000816.SZ +000818.SZ +000819.SZ +000820.SZ +000821.SZ +000822.SZ +000823.SZ +000825.SZ +000826.SZ +000828.SZ +000829.SZ +000830.SZ +000831.SZ +000833.SZ +000837.SZ +000838.SZ +000839.SZ +000848.SZ +000850.SZ +000852.SZ +000856.SZ +000858.SZ +000859.SZ +000860.SZ +000862.SZ +000863.SZ +000868.SZ +000869.SZ +000875.SZ +000876.SZ +000877.SZ +000878.SZ +000880.SZ +000881.SZ +000882.SZ +000883.SZ +000885.SZ +000886.SZ +000887.SZ +000888.SZ +000889.SZ +000890.SZ +000892.SZ +000893.SZ +000895.SZ +000897.SZ +000898.SZ +000899.SZ +000900.SZ +000901.SZ +000902.SZ +000903.SZ +000905.SZ +000906.SZ +000908.SZ +000909.SZ +000910.SZ +000911.SZ +000912.SZ +000913.SZ +000915.SZ +000917.SZ +000919.SZ +000920.SZ +000921.SZ +000922.SZ +000923.SZ +000925.SZ +000926.SZ +000927.SZ +000928.SZ +000929.SZ +000930.SZ +000931.SZ +000932.SZ +000933.SZ +000935.SZ +000936.SZ +000937.SZ +000938.SZ +000948.SZ +000949.SZ +000950.SZ +000951.SZ +000952.SZ +000953.SZ +000955.SZ +000957.SZ +000958.SZ +000959.SZ +000960.SZ +000962.SZ +000963.SZ +000965.SZ +000966.SZ +000967.SZ +000968.SZ +000969.SZ +000970.SZ +000972.SZ +000973.SZ +000975.SZ +000977.SZ +000978.SZ +000980.SZ +000981.SZ +000983.SZ +000985.SZ +000987.SZ +000988.SZ +000989.SZ +000990.SZ +000993.SZ +000995.SZ +000997.SZ +000998.SZ +000999.SZ +001201.SZ +001202.SZ +001203.SZ +001205.SZ +001206.SZ +001207.SZ +001208.SZ +001209.SZ +001210.SZ +001211.SZ +001212.SZ +001213.SZ +001215.SZ +001216.SZ +001217.SZ +001218.SZ +001219.SZ +001220.SZ +001221.SZ +001222.SZ +001223.SZ +001225.SZ +001226.SZ +001227.SZ +001228.SZ +001229.SZ +001230.SZ +001231.SZ +001233.SZ +001234.SZ +001236.SZ +001238.SZ +001239.SZ +001255.SZ +001256.SZ +001258.SZ +001259.SZ +001260.SZ +001266.SZ +001267.SZ +001268.SZ +001269.SZ +001270.SZ +001277.SZ +001278.SZ +001279.SZ +001280.SZ +001282.SZ +001283.SZ +001285.SZ +001286.SZ +001287.SZ +001288.SZ +001289.SZ +001296.SZ +001298.SZ +001299.SZ +001300.SZ +001301.SZ +001306.SZ +001308.SZ +001309.SZ +001311.SZ +001313.SZ +001314.SZ +001316.SZ +001317.SZ +001318.SZ +001319.SZ +001322.SZ +001323.SZ +001324.SZ +001325.SZ +001326.SZ +001328.SZ +001330.SZ +001331.SZ +001332.SZ +001333.SZ +001335.SZ +001336.SZ +001337.SZ +001338.SZ +001339.SZ +001356.SZ +001358.SZ +001359.SZ +001360.SZ +001366.SZ +001367.SZ +001368.SZ +001369.SZ +001373.SZ +001376.SZ +001378.SZ +001379.SZ +001380.SZ +001382.SZ +001386.SZ +001387.SZ +001388.SZ +001389.SZ +001390.SZ +001391.SZ +001395.SZ +001396.SZ +001400.SZ +001696.SZ +001872.SZ +001896.SZ +001914.SZ +001965.SZ +001979.SZ +002001.SZ +002003.SZ +002004.SZ +002005.SZ +002006.SZ +002007.SZ +002008.SZ +002009.SZ +002010.SZ +002011.SZ +002012.SZ +002014.SZ +002015.SZ +002016.SZ +002017.SZ +002019.SZ +002020.SZ +002021.SZ +002022.SZ +002023.SZ +002024.SZ +002025.SZ +002026.SZ +002027.SZ +002028.SZ +002029.SZ +002030.SZ +002031.SZ +002032.SZ +002033.SZ +002034.SZ +002035.SZ +002036.SZ +002037.SZ +002038.SZ +002039.SZ +002040.SZ +002041.SZ +002042.SZ +002043.SZ +002044.SZ +002045.SZ +002046.SZ +002047.SZ +002048.SZ +002049.SZ +002050.SZ +002051.SZ +002052.SZ +002053.SZ +002054.SZ +002055.SZ +002056.SZ +002057.SZ +002058.SZ +002059.SZ +002060.SZ +002061.SZ +002062.SZ +002063.SZ +002064.SZ +002065.SZ +002066.SZ +002067.SZ +002068.SZ +002069.SZ +002072.SZ +002073.SZ +002074.SZ +002075.SZ +002076.SZ +002077.SZ +002078.SZ +002079.SZ +002080.SZ +002081.SZ +002082.SZ +002083.SZ +002084.SZ +002085.SZ +002086.SZ +002088.SZ +002090.SZ +002091.SZ +002092.SZ +002093.SZ +002094.SZ +002095.SZ +002096.SZ +002097.SZ +002098.SZ +002099.SZ +002100.SZ +002101.SZ +002102.SZ +002103.SZ +002104.SZ +002105.SZ +002106.SZ +002107.SZ +002108.SZ +002109.SZ +002110.SZ +002111.SZ +002112.SZ +002114.SZ +002115.SZ +002116.SZ +002117.SZ +002119.SZ +002120.SZ +002121.SZ +002122.SZ +002123.SZ +002124.SZ +002125.SZ +002126.SZ +002127.SZ +002128.SZ +002129.SZ +002130.SZ +002131.SZ +002132.SZ +002133.SZ +002134.SZ +002135.SZ +002136.SZ +002137.SZ +002138.SZ +002139.SZ +002140.SZ +002141.SZ +002142.SZ +002144.SZ +002145.SZ +002146.SZ +002148.SZ +002149.SZ +002150.SZ +002151.SZ +002152.SZ +002153.SZ +002154.SZ +002155.SZ +002156.SZ +002157.SZ +002158.SZ +002159.SZ +002160.SZ +002161.SZ +002162.SZ +002163.SZ +002164.SZ +002165.SZ +002166.SZ +002167.SZ +002168.SZ +002169.SZ +002170.SZ +002171.SZ +002172.SZ +002173.SZ +002174.SZ +002175.SZ +002176.SZ +002177.SZ +002178.SZ +002179.SZ +002180.SZ +002181.SZ +002182.SZ +002183.SZ +002184.SZ +002185.SZ +002186.SZ +002187.SZ +002188.SZ +002189.SZ +002190.SZ +002191.SZ +002192.SZ +002193.SZ +002194.SZ +002195.SZ +002196.SZ +002197.SZ +002198.SZ +002199.SZ +002200.SZ +002201.SZ +002202.SZ +002203.SZ +002204.SZ +002205.SZ +002206.SZ +002207.SZ +002208.SZ +002209.SZ +002210.SZ +002211.SZ +002212.SZ +002213.SZ +002214.SZ +002215.SZ +002216.SZ +002217.SZ +002218.SZ +002219.SZ +002221.SZ +002222.SZ +002223.SZ +002224.SZ +002225.SZ +002226.SZ +002227.SZ +002228.SZ +002229.SZ +002230.SZ +002231.SZ +002232.SZ +002233.SZ +002234.SZ +002235.SZ +002236.SZ +002237.SZ +002238.SZ +002239.SZ +002240.SZ +002241.SZ +002242.SZ +002243.SZ +002244.SZ +002245.SZ +002246.SZ +002247.SZ +002248.SZ +002249.SZ +002250.SZ +002251.SZ +002252.SZ +002253.SZ +002254.SZ +002255.SZ +002256.SZ +002258.SZ +002259.SZ +002261.SZ +002262.SZ +002263.SZ +002264.SZ +002265.SZ +002266.SZ +002267.SZ +002268.SZ +002269.SZ +002270.SZ +002271.SZ +002272.SZ +002273.SZ +002274.SZ +002275.SZ +002276.SZ +002277.SZ +002278.SZ +002279.SZ +002281.SZ +002282.SZ +002283.SZ +002284.SZ +002285.SZ +002286.SZ +002287.SZ +002289.SZ +002290.SZ +002291.SZ +002292.SZ +002293.SZ +002294.SZ +002295.SZ +002296.SZ +002297.SZ +002298.SZ +002299.SZ +002300.SZ +002301.SZ +002302.SZ +002303.SZ +002304.SZ +002305.SZ +002306.SZ +002307.SZ +002309.SZ +002310.SZ +002311.SZ +002312.SZ +002313.SZ +002314.SZ +002315.SZ +002316.SZ +002317.SZ +002318.SZ +002319.SZ +002320.SZ +002321.SZ +002322.SZ +002323.SZ +002324.SZ +002326.SZ +002327.SZ +002328.SZ +002329.SZ +002330.SZ +002331.SZ +002332.SZ +002333.SZ +002334.SZ +002335.SZ +002337.SZ +002338.SZ +002339.SZ +002340.SZ +002342.SZ +002343.SZ +002344.SZ +002345.SZ +002346.SZ +002347.SZ +002348.SZ +002349.SZ +002350.SZ +002351.SZ +002352.SZ +002353.SZ +002354.SZ +002355.SZ +002356.SZ +002357.SZ +002358.SZ +002360.SZ +002361.SZ +002362.SZ +002363.SZ +002364.SZ +002365.SZ +002366.SZ +002367.SZ +002368.SZ +002369.SZ +002370.SZ +002371.SZ +002372.SZ +002373.SZ +002374.SZ +002375.SZ +002376.SZ +002377.SZ +002378.SZ +002379.SZ +002380.SZ +002381.SZ +002382.SZ +002383.SZ +002384.SZ +002385.SZ +002386.SZ +002387.SZ +002388.SZ +002389.SZ +002390.SZ +002391.SZ +002392.SZ +002393.SZ +002394.SZ +002395.SZ +002396.SZ +002397.SZ +002398.SZ +002399.SZ +002400.SZ +002401.SZ +002402.SZ +002403.SZ +002404.SZ +002405.SZ +002406.SZ +002407.SZ +002408.SZ +002409.SZ +002410.SZ +002412.SZ +002413.SZ +002414.SZ +002415.SZ +002416.SZ +002418.SZ +002419.SZ +002420.SZ +002421.SZ +002422.SZ +002423.SZ +002424.SZ +002425.SZ +002426.SZ +002427.SZ +002428.SZ +002429.SZ +002430.SZ +002431.SZ +002432.SZ +002434.SZ +002436.SZ +002437.SZ +002438.SZ +002439.SZ +002440.SZ +002441.SZ +002442.SZ +002443.SZ +002444.SZ +002445.SZ +002446.SZ +002448.SZ +002449.SZ +002451.SZ +002452.SZ +002453.SZ +002454.SZ +002455.SZ +002456.SZ +002457.SZ +002458.SZ +002459.SZ +002460.SZ +002461.SZ +002462.SZ +002463.SZ +002465.SZ +002466.SZ +002467.SZ +002468.SZ +002469.SZ +002470.SZ +002471.SZ +002472.SZ +002474.SZ +002475.SZ +002476.SZ +002478.SZ +002479.SZ +002480.SZ +002481.SZ +002482.SZ +002483.SZ +002484.SZ +002485.SZ +002486.SZ +002487.SZ +002488.SZ +002489.SZ +002490.SZ +002491.SZ +002492.SZ +002493.SZ +002494.SZ +002495.SZ +002496.SZ +002497.SZ +002498.SZ +002500.SZ +002501.SZ +002506.SZ +002507.SZ +002508.SZ +002510.SZ +002511.SZ +002512.SZ +002513.SZ +002514.SZ +002515.SZ +002516.SZ +002517.SZ +002518.SZ +002519.SZ +002520.SZ +002521.SZ +002522.SZ +002523.SZ +002524.SZ +002526.SZ +002527.SZ +002528.SZ +002529.SZ +002530.SZ +002531.SZ +002532.SZ +002533.SZ +002534.SZ +002535.SZ +002536.SZ +002537.SZ +002538.SZ +002539.SZ +002540.SZ +002541.SZ +002542.SZ +002543.SZ +002544.SZ +002545.SZ +002546.SZ +002547.SZ +002548.SZ +002549.SZ +002550.SZ +002551.SZ +002552.SZ +002553.SZ +002554.SZ +002555.SZ +002556.SZ +002557.SZ +002558.SZ +002559.SZ +002560.SZ +002561.SZ +002562.SZ +002563.SZ +002564.SZ +002565.SZ +002566.SZ +002567.SZ +002568.SZ +002569.SZ +002570.SZ +002571.SZ +002572.SZ +002573.SZ +002574.SZ +002575.SZ +002576.SZ +002577.SZ +002578.SZ +002579.SZ +002580.SZ +002581.SZ +002582.SZ +002583.SZ +002584.SZ +002585.SZ +002586.SZ +002587.SZ +002588.SZ +002589.SZ +002590.SZ +002591.SZ +002592.SZ +002593.SZ +002594.SZ +002595.SZ +002596.SZ +002597.SZ +002598.SZ +002599.SZ +002600.SZ +002601.SZ +002602.SZ +002603.SZ +002605.SZ +002606.SZ +002607.SZ +002608.SZ +002609.SZ +002611.SZ +002612.SZ +002613.SZ +002614.SZ +002615.SZ +002616.SZ +002617.SZ +002620.SZ +002622.SZ +002623.SZ +002624.SZ +002625.SZ +002626.SZ +002627.SZ +002628.SZ +002629.SZ +002630.SZ +002631.SZ +002632.SZ +002633.SZ +002634.SZ +002635.SZ +002636.SZ +002637.SZ +002638.SZ +002639.SZ +002640.SZ +002641.SZ +002642.SZ +002643.SZ +002644.SZ +002645.SZ +002646.SZ +002647.SZ +002648.SZ +002649.SZ +002650.SZ +002651.SZ +002652.SZ +002653.SZ +002654.SZ +002655.SZ +002656.SZ +002657.SZ +002658.SZ +002659.SZ +002660.SZ +002661.SZ +002662.SZ +002663.SZ +002664.SZ +002666.SZ +002667.SZ +002668.SZ +002669.SZ +002670.SZ +002671.SZ +002672.SZ +002673.SZ +002674.SZ +002675.SZ +002676.SZ +002677.SZ +002678.SZ +002679.SZ +002681.SZ +002682.SZ +002683.SZ +002685.SZ +002686.SZ +002687.SZ +002688.SZ +002689.SZ +002690.SZ +002691.SZ +002692.SZ +002693.SZ +002694.SZ +002695.SZ +002696.SZ +002697.SZ +002698.SZ +002700.SZ +002701.SZ +002702.SZ +002703.SZ +002705.SZ +002706.SZ +002707.SZ +002708.SZ +002709.SZ +002712.SZ +002713.SZ +002714.SZ +002715.SZ +002716.SZ +002717.SZ +002718.SZ +002719.SZ +002721.SZ +002722.SZ +002723.SZ +002724.SZ +002725.SZ +002726.SZ +002727.SZ +002728.SZ +002729.SZ +002730.SZ +002731.SZ +002732.SZ +002733.SZ +002734.SZ +002735.SZ +002736.SZ +002737.SZ +002738.SZ +002739.SZ +002741.SZ +002742.SZ +002743.SZ +002745.SZ +002746.SZ +002747.SZ +002748.SZ +002749.SZ +002752.SZ +002753.SZ +002755.SZ +002756.SZ +002757.SZ +002758.SZ +002759.SZ +002760.SZ +002761.SZ +002762.SZ +002763.SZ +002765.SZ +002766.SZ +002767.SZ +002768.SZ +002769.SZ +002771.SZ +002772.SZ +002773.SZ +002774.SZ +002775.SZ +002777.SZ +002778.SZ +002779.SZ +002780.SZ +002782.SZ +002783.SZ +002785.SZ +002786.SZ +002787.SZ +002788.SZ +002789.SZ +002790.SZ +002791.SZ +002792.SZ +002793.SZ +002795.SZ +002796.SZ +002797.SZ +002798.SZ +002799.SZ +002800.SZ +002801.SZ +002802.SZ +002803.SZ +002805.SZ +002806.SZ +002807.SZ +002808.SZ +002809.SZ +002810.SZ +002811.SZ +002812.SZ +002813.SZ +002815.SZ +002816.SZ +002817.SZ +002818.SZ +002819.SZ +002820.SZ +002821.SZ +002822.SZ +002823.SZ +002824.SZ +002825.SZ +002826.SZ +002827.SZ +002828.SZ +002829.SZ +002830.SZ +002831.SZ +002832.SZ +002833.SZ +002835.SZ +002836.SZ +002837.SZ +002838.SZ +002839.SZ +002840.SZ +002841.SZ +002842.SZ +002843.SZ +002845.SZ +002846.SZ +002847.SZ +002848.SZ +002849.SZ +002850.SZ +002851.SZ +002852.SZ +002853.SZ +002855.SZ +002856.SZ +002857.SZ +002858.SZ +002859.SZ +002860.SZ +002861.SZ +002862.SZ +002863.SZ +002864.SZ +002865.SZ +002866.SZ +002867.SZ +002868.SZ +002869.SZ +002870.SZ +002871.SZ +002872.SZ +002873.SZ +002875.SZ +002876.SZ +002877.SZ +002878.SZ +002879.SZ +002880.SZ +002881.SZ +002882.SZ +002883.SZ +002884.SZ +002885.SZ +002886.SZ +002887.SZ +002888.SZ +002889.SZ +002890.SZ +002891.SZ +002892.SZ +002893.SZ +002895.SZ +002896.SZ +002897.SZ +002898.SZ +002899.SZ +002900.SZ +002901.SZ +002902.SZ +002903.SZ +002905.SZ +002906.SZ +002907.SZ +002908.SZ +002909.SZ +002910.SZ +002911.SZ +002912.SZ +002913.SZ +002915.SZ +002916.SZ +002917.SZ +002918.SZ +002919.SZ +002920.SZ +002921.SZ +002922.SZ +002923.SZ +002925.SZ +002926.SZ +002927.SZ +002928.SZ +002929.SZ +002930.SZ +002931.SZ +002932.SZ +002933.SZ +002935.SZ +002936.SZ +002937.SZ +002938.SZ +002939.SZ +002940.SZ +002941.SZ +002942.SZ +002943.SZ +002945.SZ +002946.SZ +002947.SZ +002948.SZ +002949.SZ +002950.SZ +002951.SZ +002952.SZ +002953.SZ +002955.SZ +002956.SZ +002957.SZ +002958.SZ +002959.SZ +002960.SZ +002961.SZ +002962.SZ +002963.SZ +002965.SZ +002966.SZ +002967.SZ +002968.SZ +002969.SZ +002970.SZ +002971.SZ +002972.SZ +002973.SZ +002975.SZ +002976.SZ +002977.SZ +002978.SZ +002979.SZ +002980.SZ +002981.SZ +002982.SZ +002983.SZ +002984.SZ +002985.SZ +002986.SZ +002987.SZ +002988.SZ +002989.SZ +002990.SZ +002991.SZ +002992.SZ +002993.SZ +002995.SZ +002996.SZ +002997.SZ +002998.SZ +002999.SZ +003000.SZ +003001.SZ +003002.SZ +003003.SZ +003004.SZ +003005.SZ +003006.SZ +003007.SZ +003008.SZ +003009.SZ +003010.SZ +003011.SZ +003012.SZ +003013.SZ +003015.SZ +003016.SZ +003017.SZ +003018.SZ +003019.SZ +003020.SZ +003021.SZ +003022.SZ +003023.SZ +003025.SZ +003026.SZ +003027.SZ +003028.SZ +003029.SZ +003030.SZ +003031.SZ +003032.SZ +003033.SZ +003035.SZ +003036.SZ +003037.SZ +003038.SZ +003039.SZ +003040.SZ +003041.SZ +003042.SZ +003043.SZ +003816.SZ +300001.SZ +300002.SZ +300003.SZ +300004.SZ +300005.SZ +300006.SZ +300007.SZ +300008.SZ +300009.SZ +300010.SZ +300011.SZ +300012.SZ +300013.SZ +300014.SZ +300015.SZ +300016.SZ +300017.SZ +300018.SZ +300019.SZ +300020.SZ +300021.SZ +300022.SZ +300024.SZ +300025.SZ +300026.SZ +300027.SZ +300029.SZ +300030.SZ +300031.SZ +300032.SZ +300033.SZ +300034.SZ +300035.SZ +300036.SZ +300037.SZ +300039.SZ +300040.SZ +300041.SZ +300042.SZ +300043.SZ +300044.SZ +300045.SZ +300046.SZ +300047.SZ +300048.SZ +300049.SZ +300050.SZ +300051.SZ +300052.SZ +300053.SZ +300054.SZ +300055.SZ +300056.SZ +300057.SZ +300058.SZ +300059.SZ +300061.SZ +300062.SZ +300063.SZ +300065.SZ +300066.SZ +300067.SZ +300068.SZ +300069.SZ +300070.SZ +300071.SZ +300072.SZ +300073.SZ +300074.SZ +300075.SZ +300076.SZ +300077.SZ +300078.SZ +300079.SZ +300080.SZ +300081.SZ +300082.SZ +300083.SZ +300084.SZ +300085.SZ +300086.SZ +300087.SZ +300088.SZ +300091.SZ +300092.SZ +300093.SZ +300094.SZ +300095.SZ +300096.SZ +300097.SZ +300098.SZ +300099.SZ +300100.SZ +300101.SZ +300102.SZ +300103.SZ +300105.SZ +300106.SZ +300107.SZ +300109.SZ +300110.SZ +300111.SZ +300112.SZ +300113.SZ +300115.SZ +300118.SZ +300119.SZ +300120.SZ +300121.SZ +300122.SZ +300123.SZ +300124.SZ +300125.SZ +300126.SZ +300127.SZ +300128.SZ +300129.SZ +300130.SZ +300131.SZ +300132.SZ +300133.SZ +300134.SZ +300135.SZ +300136.SZ +300137.SZ +300138.SZ +300139.SZ +300140.SZ +300141.SZ +300142.SZ +300143.SZ +300144.SZ +300145.SZ +300146.SZ +300147.SZ +300148.SZ +300149.SZ +300150.SZ +300151.SZ +300152.SZ +300153.SZ +300154.SZ +300155.SZ +300157.SZ +300158.SZ +300159.SZ +300160.SZ +300161.SZ +300162.SZ +300163.SZ +300164.SZ +300165.SZ +300166.SZ +300167.SZ +300168.SZ +300169.SZ +300170.SZ +300171.SZ +300172.SZ +300173.SZ +300174.SZ +300175.SZ +300176.SZ +300177.SZ +300179.SZ +300180.SZ +300181.SZ +300182.SZ +300183.SZ +300184.SZ +300185.SZ +300187.SZ +300188.SZ +300189.SZ +300190.SZ +300191.SZ +300192.SZ +300193.SZ +300194.SZ +300195.SZ +300196.SZ +300197.SZ +300198.SZ +300199.SZ +300200.SZ +300201.SZ +300203.SZ +300204.SZ +300205.SZ +300206.SZ +300207.SZ +300209.SZ +300210.SZ +300211.SZ +300212.SZ +300213.SZ +300214.SZ +300215.SZ +300217.SZ +300218.SZ +300219.SZ +300220.SZ +300221.SZ +300222.SZ +300223.SZ +300224.SZ +300225.SZ +300226.SZ +300227.SZ +300228.SZ +300229.SZ +300230.SZ +300231.SZ +300232.SZ +300233.SZ +300234.SZ +300235.SZ +300236.SZ +300237.SZ +300238.SZ +300239.SZ +300240.SZ +300241.SZ +300242.SZ +300243.SZ +300244.SZ +300245.SZ +300246.SZ +300247.SZ +300248.SZ +300249.SZ +300250.SZ +300251.SZ +300252.SZ +300253.SZ +300254.SZ +300255.SZ +300256.SZ +300257.SZ +300258.SZ +300259.SZ +300260.SZ +300261.SZ +300263.SZ +300264.SZ +300265.SZ +300266.SZ +300267.SZ +300268.SZ +300269.SZ +300270.SZ +300271.SZ +300272.SZ +300274.SZ +300275.SZ +300276.SZ +300277.SZ +300278.SZ +300279.SZ +300281.SZ +300283.SZ +300284.SZ +300285.SZ +300286.SZ +300287.SZ +300288.SZ +300289.SZ +300290.SZ +300291.SZ +300292.SZ +300293.SZ +300294.SZ +300295.SZ +300296.SZ +300298.SZ +300299.SZ +300300.SZ +300301.SZ +300302.SZ +300303.SZ +300304.SZ +300305.SZ +300306.SZ +300307.SZ +300308.SZ +300310.SZ +300311.SZ +300313.SZ +300314.SZ +300315.SZ +300316.SZ +300317.SZ +300318.SZ +300319.SZ +300320.SZ +300321.SZ +300322.SZ +300323.SZ +300324.SZ +300326.SZ +300327.SZ +300328.SZ +300329.SZ +300331.SZ +300332.SZ +300333.SZ +300334.SZ +300335.SZ +300337.SZ +300338.SZ +300339.SZ +300340.SZ +300341.SZ +300342.SZ +300343.SZ +300344.SZ +300345.SZ +300346.SZ +300347.SZ +300348.SZ +300349.SZ +300350.SZ +300351.SZ +300352.SZ +300353.SZ +300354.SZ +300355.SZ +300357.SZ +300358.SZ +300359.SZ +300360.SZ +300363.SZ +300364.SZ +300365.SZ +300366.SZ +300368.SZ +300369.SZ +300370.SZ +300371.SZ +300373.SZ +300374.SZ +300375.SZ +300376.SZ +300377.SZ +300378.SZ +300380.SZ +300381.SZ +300382.SZ +300383.SZ +300384.SZ +300385.SZ +300386.SZ +300387.SZ +300388.SZ +300389.SZ +300390.SZ +300391.SZ +300393.SZ +300394.SZ +300395.SZ +300396.SZ +300397.SZ +300398.SZ +300399.SZ +300400.SZ +300401.SZ +300402.SZ +300403.SZ +300404.SZ +300405.SZ +300406.SZ +300407.SZ +300408.SZ +300409.SZ +300410.SZ +300411.SZ +300412.SZ +300413.SZ +300414.SZ +300415.SZ +300416.SZ +300417.SZ +300418.SZ +300419.SZ +300420.SZ +300421.SZ +300422.SZ +300423.SZ +300424.SZ +300425.SZ +300426.SZ +300427.SZ +300428.SZ +300429.SZ +300430.SZ +300432.SZ +300433.SZ +300434.SZ +300435.SZ +300436.SZ +300437.SZ +300438.SZ +300439.SZ +300440.SZ +300441.SZ +300442.SZ +300443.SZ +300444.SZ +300445.SZ +300446.SZ +300447.SZ +300448.SZ +300449.SZ +300450.SZ +300451.SZ +300452.SZ +300453.SZ +300454.SZ +300455.SZ +300456.SZ +300457.SZ +300458.SZ +300459.SZ +300460.SZ +300461.SZ +300462.SZ +300463.SZ +300464.SZ +300465.SZ +300466.SZ +300467.SZ +300468.SZ +300469.SZ +300470.SZ +300471.SZ +300472.SZ +300473.SZ +300474.SZ +300475.SZ +300476.SZ +300477.SZ +300478.SZ +300479.SZ +300480.SZ +300481.SZ +300482.SZ +300483.SZ +300484.SZ +300485.SZ +300486.SZ +300487.SZ +300488.SZ +300489.SZ +300490.SZ +300491.SZ +300492.SZ +300493.SZ +300494.SZ +300496.SZ +300497.SZ +300498.SZ +300499.SZ +300500.SZ +300501.SZ +300502.SZ +300503.SZ +300504.SZ +300505.SZ +300506.SZ +300507.SZ +300508.SZ +300509.SZ +300510.SZ +300511.SZ +300512.SZ +300513.SZ +300514.SZ +300515.SZ +300516.SZ +300517.SZ +300518.SZ +300519.SZ +300520.SZ +300521.SZ +300522.SZ +300523.SZ +300525.SZ +300527.SZ +300528.SZ +300529.SZ +300530.SZ +300531.SZ +300532.SZ +300533.SZ +300534.SZ +300535.SZ +300536.SZ +300537.SZ +300538.SZ +300539.SZ +300540.SZ +300541.SZ +300542.SZ +300543.SZ +300545.SZ +300546.SZ +300547.SZ +300548.SZ +300549.SZ +300550.SZ +300551.SZ +300552.SZ +300553.SZ +300554.SZ +300555.SZ +300556.SZ +300557.SZ +300558.SZ +300559.SZ +300560.SZ +300561.SZ +300562.SZ +300563.SZ +300564.SZ +300565.SZ +300566.SZ +300567.SZ +300568.SZ +300569.SZ +300570.SZ +300571.SZ +300572.SZ +300573.SZ +300575.SZ +300576.SZ +300577.SZ +300578.SZ +300579.SZ +300580.SZ +300581.SZ +300582.SZ +300583.SZ +300584.SZ +300585.SZ +300586.SZ +300587.SZ +300588.SZ +300589.SZ +300590.SZ +300591.SZ +300592.SZ +300593.SZ +300594.SZ +300595.SZ +300596.SZ +300597.SZ +300598.SZ +300599.SZ +300600.SZ +300601.SZ +300602.SZ +300603.SZ +300604.SZ +300605.SZ +300606.SZ +300607.SZ +300608.SZ +300609.SZ +300610.SZ +300611.SZ +300612.SZ +300613.SZ +300614.SZ +300615.SZ +300616.SZ +300617.SZ +300618.SZ +300619.SZ +300620.SZ +300621.SZ +300622.SZ +300623.SZ +300624.SZ +300625.SZ +300626.SZ +300627.SZ +300628.SZ +300629.SZ +300631.SZ +300632.SZ +300633.SZ +300634.SZ +300635.SZ +300636.SZ +300637.SZ +300638.SZ +300639.SZ +300640.SZ +300641.SZ +300642.SZ +300643.SZ +300644.SZ +300645.SZ +300647.SZ +300648.SZ +300649.SZ +300650.SZ +300651.SZ +300652.SZ +300653.SZ +300654.SZ +300655.SZ +300656.SZ +300657.SZ +300658.SZ +300659.SZ +300660.SZ +300661.SZ +300662.SZ +300663.SZ +300664.SZ +300665.SZ +300666.SZ +300667.SZ +300668.SZ +300669.SZ +300670.SZ +300671.SZ +300672.SZ +300673.SZ +300674.SZ +300675.SZ +300676.SZ +300677.SZ +300678.SZ +300679.SZ +300680.SZ +300681.SZ +300682.SZ +300683.SZ +300684.SZ +300685.SZ +300686.SZ +300687.SZ +300688.SZ +300689.SZ +300690.SZ +300691.SZ +300692.SZ +300693.SZ +300694.SZ +300695.SZ +300696.SZ +300697.SZ +300698.SZ +300699.SZ +300700.SZ +300701.SZ +300702.SZ +300703.SZ +300705.SZ +300706.SZ +300707.SZ +300708.SZ +300709.SZ +300710.SZ +300711.SZ +300712.SZ +300713.SZ +300715.SZ +300716.SZ +300717.SZ +300718.SZ +300719.SZ +300720.SZ +300721.SZ +300722.SZ +300723.SZ +300724.SZ +300725.SZ +300726.SZ +300727.SZ +300729.SZ +300730.SZ +300731.SZ +300732.SZ +300733.SZ +300735.SZ +300736.SZ +300737.SZ +300738.SZ +300739.SZ +300740.SZ +300741.SZ +300743.SZ +300745.SZ +300746.SZ +300747.SZ +300748.SZ +300749.SZ +300750.SZ +300751.SZ +300752.SZ +300753.SZ +300755.SZ +300756.SZ +300757.SZ +300758.SZ +300759.SZ +300760.SZ +300761.SZ +300762.SZ +300763.SZ +300765.SZ +300766.SZ +300767.SZ +300768.SZ +300769.SZ +300770.SZ +300771.SZ +300772.SZ +300773.SZ +300774.SZ +300775.SZ +300776.SZ +300777.SZ +300778.SZ +300779.SZ +300780.SZ +300781.SZ +300782.SZ +300783.SZ +300784.SZ +300785.SZ +300786.SZ +300787.SZ +300788.SZ +300789.SZ +300790.SZ +300791.SZ +300792.SZ +300793.SZ +300795.SZ +300796.SZ +300797.SZ +300798.SZ +300800.SZ +300801.SZ +300802.SZ +300803.SZ +300804.SZ +300805.SZ +300806.SZ +300807.SZ +300808.SZ +300809.SZ +300810.SZ +300811.SZ +300812.SZ +300813.SZ +300814.SZ +300815.SZ +300816.SZ +300817.SZ +300818.SZ +300819.SZ +300820.SZ +300821.SZ +300822.SZ +300823.SZ +300824.SZ +300825.SZ +300826.SZ +300827.SZ +300828.SZ +300829.SZ +300830.SZ +300831.SZ +300832.SZ +300833.SZ +300834.SZ +300835.SZ +300836.SZ +300837.SZ +300838.SZ +300839.SZ +300840.SZ +300841.SZ +300842.SZ +300843.SZ +300844.SZ +300845.SZ +300846.SZ +300847.SZ +300848.SZ +300849.SZ +300850.SZ +300851.SZ +300852.SZ +300853.SZ +300854.SZ +300855.SZ +300856.SZ +300857.SZ +300858.SZ +300859.SZ +300860.SZ +300861.SZ +300862.SZ +300863.SZ +300864.SZ +300865.SZ +300866.SZ +300867.SZ +300868.SZ +300869.SZ +300870.SZ +300871.SZ +300872.SZ +300873.SZ +300875.SZ +300876.SZ +300877.SZ +300878.SZ +300879.SZ +300880.SZ +300881.SZ +300882.SZ +300883.SZ +300884.SZ +300885.SZ +300886.SZ +300887.SZ +300888.SZ +300889.SZ +300890.SZ +300891.SZ +300892.SZ +300893.SZ +300894.SZ +300895.SZ +300896.SZ +300897.SZ +300898.SZ +300899.SZ +300900.SZ +300901.SZ +300902.SZ +300903.SZ +300904.SZ +300905.SZ +300906.SZ +300907.SZ +300908.SZ +300909.SZ +300910.SZ +300911.SZ +300912.SZ +300913.SZ +300915.SZ +300916.SZ +300917.SZ +300918.SZ +300919.SZ +300920.SZ +300921.SZ +300922.SZ +300923.SZ +300925.SZ +300926.SZ +300927.SZ +300928.SZ +300929.SZ +300930.SZ +300931.SZ +300932.SZ +300933.SZ +300935.SZ +300936.SZ +300937.SZ +300938.SZ +300939.SZ +300940.SZ +300941.SZ +300942.SZ +300943.SZ +300945.SZ +300946.SZ +300947.SZ +300948.SZ +300949.SZ +300950.SZ +300951.SZ +300952.SZ +300953.SZ +300955.SZ +300956.SZ +300957.SZ +300958.SZ +300959.SZ +300960.SZ +300961.SZ +300962.SZ +300963.SZ +300964.SZ +300965.SZ +300966.SZ +300967.SZ +300968.SZ +300969.SZ +300970.SZ +300971.SZ +300972.SZ +300973.SZ +300975.SZ +300976.SZ +300977.SZ +300978.SZ +300979.SZ +300980.SZ +300981.SZ +300982.SZ +300983.SZ +300984.SZ +300985.SZ +300986.SZ +300987.SZ +300988.SZ +300989.SZ +300990.SZ +300991.SZ +300992.SZ +300993.SZ +300994.SZ +300995.SZ +300996.SZ +300997.SZ +300998.SZ +300999.SZ +301000.SZ +301001.SZ +301002.SZ +301003.SZ +301004.SZ +301005.SZ +301006.SZ +301007.SZ +301008.SZ +301009.SZ +301010.SZ +301011.SZ +301012.SZ +301013.SZ +301015.SZ +301016.SZ +301017.SZ +301018.SZ +301019.SZ +301020.SZ +301021.SZ +301022.SZ +301023.SZ +301024.SZ +301025.SZ +301026.SZ +301027.SZ +301028.SZ +301029.SZ +301030.SZ +301031.SZ +301032.SZ +301033.SZ +301035.SZ +301036.SZ +301037.SZ +301038.SZ +301039.SZ +301040.SZ +301041.SZ +301042.SZ +301043.SZ +301045.SZ +301046.SZ +301047.SZ +301048.SZ +301049.SZ +301050.SZ +301051.SZ +301052.SZ +301053.SZ +301055.SZ +301056.SZ +301057.SZ +301058.SZ +301059.SZ +301060.SZ +301061.SZ +301062.SZ +301063.SZ +301065.SZ +301066.SZ +301067.SZ +301068.SZ +301069.SZ +301070.SZ +301071.SZ +301072.SZ +301073.SZ +301075.SZ +301076.SZ +301077.SZ +301078.SZ +301079.SZ +301080.SZ +301081.SZ +301082.SZ +301083.SZ +301085.SZ +301086.SZ +301087.SZ +301088.SZ +301089.SZ +301090.SZ +301091.SZ +301092.SZ +301093.SZ +301095.SZ +301096.SZ +301097.SZ +301098.SZ +301099.SZ +301100.SZ +301101.SZ +301102.SZ +301103.SZ +301105.SZ +301106.SZ +301107.SZ +301108.SZ +301109.SZ +301110.SZ +301111.SZ +301112.SZ +301113.SZ +301115.SZ +301116.SZ +301117.SZ +301118.SZ +301119.SZ +301120.SZ +301121.SZ +301122.SZ +301123.SZ +301125.SZ +301126.SZ +301127.SZ +301128.SZ +301129.SZ +301130.SZ +301131.SZ +301132.SZ +301133.SZ +301135.SZ +301136.SZ +301137.SZ +301138.SZ +301139.SZ +301141.SZ +301148.SZ +301149.SZ +301150.SZ +301151.SZ +301152.SZ +301153.SZ +301155.SZ +301156.SZ +301157.SZ +301158.SZ +301159.SZ +301160.SZ +301161.SZ +301162.SZ +301163.SZ +301165.SZ +301166.SZ +301167.SZ +301168.SZ +301169.SZ +301170.SZ +301171.SZ +301172.SZ +301173.SZ +301175.SZ +301176.SZ +301177.SZ +301178.SZ +301179.SZ +301180.SZ +301181.SZ +301182.SZ +301183.SZ +301185.SZ +301186.SZ +301187.SZ +301188.SZ +301189.SZ +301190.SZ +301191.SZ +301192.SZ +301193.SZ +301195.SZ +301196.SZ +301197.SZ +301198.SZ +301199.SZ +301200.SZ +301201.SZ +301202.SZ +301203.SZ +301205.SZ +301206.SZ +301207.SZ +301208.SZ +301209.SZ +301210.SZ +301211.SZ +301212.SZ +301213.SZ +301215.SZ +301216.SZ +301217.SZ +301218.SZ +301219.SZ +301220.SZ +301221.SZ +301222.SZ +301223.SZ +301225.SZ +301226.SZ +301227.SZ +301228.SZ +301229.SZ +301230.SZ +301231.SZ +301232.SZ +301233.SZ +301234.SZ +301235.SZ +301236.SZ +301237.SZ +301238.SZ +301239.SZ +301246.SZ +301248.SZ +301251.SZ +301252.SZ +301255.SZ +301256.SZ +301257.SZ +301258.SZ +301259.SZ +301260.SZ +301261.SZ +301262.SZ +301263.SZ +301265.SZ +301266.SZ +301267.SZ +301268.SZ +301269.SZ +301270.SZ +301272.SZ +301273.SZ +301275.SZ +301276.SZ +301277.SZ +301278.SZ +301279.SZ +301280.SZ +301281.SZ +301282.SZ +301283.SZ +301285.SZ +301286.SZ +301287.SZ +301288.SZ +301289.SZ +301290.SZ +301291.SZ +301292.SZ +301293.SZ +301295.SZ +301296.SZ +301297.SZ +301298.SZ +301299.SZ +301300.SZ +301301.SZ +301302.SZ +301303.SZ +301305.SZ +301306.SZ +301307.SZ +301308.SZ +301309.SZ +301310.SZ +301311.SZ +301312.SZ +301313.SZ +301314.SZ +301315.SZ +301316.SZ +301317.SZ +301318.SZ +301319.SZ +301320.SZ +301321.SZ +301322.SZ +301323.SZ +301325.SZ +301326.SZ +301327.SZ +301328.SZ +301329.SZ +301330.SZ +301331.SZ +301332.SZ +301333.SZ +301335.SZ +301336.SZ +301337.SZ +301338.SZ +301339.SZ +301345.SZ +301348.SZ +301349.SZ +301353.SZ +301355.SZ +301356.SZ +301357.SZ +301358.SZ +301359.SZ +301360.SZ +301361.SZ +301362.SZ +301363.SZ +301365.SZ +301366.SZ +301367.SZ +301368.SZ +301369.SZ +301370.SZ +301371.SZ +301372.SZ +301373.SZ +301376.SZ +301377.SZ +301378.SZ diff --git a/fetch_daily_update.py b/fetch_daily_update.py new file mode 100644 index 0000000..8e48ea5 --- /dev/null +++ b/fetch_daily_update.py @@ -0,0 +1,264 @@ +""" +A股每日增量数据更新脚本 +功能: +1. 检查所有股票最新数据日期 +2. 补齐缺失的交易日数据 +3. 支持单次运行和定时运行 + +用法: +python3 fetch_daily_update.py # 更新所有股票缺失数据 +python3 fetch_daily_update.py --check # 只检查不更新 +python3 fetch_daily_update.py --days 5 # 补最近5天的数据 +""" + +import tushare as ts +import pandas as pd +import sqlite3 +import os +import time +from datetime import datetime, timedelta +from pathlib import Path +import argparse + +# 配置 +BASE_DIR = Path(__file__).parent +DATA_DIR = BASE_DIR / 'data' +TEMP_DIR = DATA_DIR / 'temp' +DB_FILE = DATA_DIR / 'progress.db' +STOCK_LIST_FILE = BASE_DIR / 'A股股票列表.csv' + +REQUEST_INTERVAL = 0.3 # 增量数据请求间隔更短 + + +def setup_tushare(): + """初始化tushare""" + token = os.environ.get('TUSHARE_TOKEN', '') + if not token: + config_file = BASE_DIR / 'config.txt' + if config_file.exists(): + token = config_file.read_text().strip() + if not token: + raise ValueError("缺少 Tushare Token") + ts.set_token(token) + return ts.pro_api() + + +def get_latest_dates(): + """获取每只股票的最新数据日期""" + main_file = DATA_DIR / 'stock_daily_data.parquet' + if not main_file.exists(): + return {} + + df = pd.read_parquet(main_file) + latest = df.groupby('ts_code')['trade_date'].max() + return dict(latest) + + +def get_all_stock_codes(): + """获取所有股票代码""" + conn = sqlite3.connect(DB_FILE) + cursor = conn.cursor() + cursor.execute("SELECT ts_code FROM progress WHERE status = 'completed'") + codes = [row[0] for row in cursor.fetchall()] + conn.close() + return codes + + +def is_trading_day(date_str): + """判断是否为交易日(简单版:排除周末)""" + d = datetime.strptime(date_str, '%Y%m%d') + return d.weekday() < 5 # 周一到周五 + + +def get_trade_dates(start_date, end_date): + """获取日期范围内的可能交易日""" + start = datetime.strptime(start_date, '%Y%m%d') + end = datetime.strptime(end_date, '%Y%m%d') + + trade_dates = [] + current = start + while current <= end: + if current.weekday() < 5: # 周一到周五 + trade_dates.append(current.strftime('%Y%m%d')) + current += timedelta(days=1) + + return trade_dates + + +def get_missing_dates(pro, latest_dates, codes, days=30): + """找出需要更新的日期范围""" + today = datetime.now().strftime('%Y%m%d') + + # 使用简单交易日判断(排除周末) + start = (datetime.now() - timedelta(days=days)).strftime('%Y%m%d') + trade_dates = get_trade_dates(start, today) + + # 找出每个股票缺失的交易日 + missing_info = {} + for ts_code in codes: + latest = latest_dates.get(ts_code, '20100101') + missing = [d for d in trade_dates if d > latest and is_trading_day(d)] + if missing: + missing_info[ts_code] = { + 'latest': latest, + 'missing': missing, + 'missing_count': len(missing) + } + + return missing_info, trade_dates + + +def fetch_missing_data(pro, missing_info, batch_size=100): + """批量获取缺失数据""" + total_stocks = len(missing_info) + print(f"\n需要更新 {total_stocks} 只股票") + + # 计算需要获取的日期范围 + all_missing_dates = set() + for info in missing_info.values(): + all_missing_dates.update(info['missing']) + + if not all_missing_dates: + print("没有缺失数据") + return 0 + + start_date = min(all_missing_dates) + end_date = max(all_missing_dates) + print(f"数据范围: {start_date} ~ {end_date}") + + # 批量获取数据(tushare支持批量查询) + codes = list(missing_info.keys()) + total_records = 0 + batch_count = 0 + + main_file = DATA_DIR / 'stock_daily_data.parquet' + existing_df = pd.read_parquet(main_file) if main_file.exists() else None + + print(f"\n开始获取增量数据...") + print("-" * 50) + + for i, ts_code in enumerate(codes): + try: + latest = missing_info[ts_code]['latest'] + # 从最新日期的下一天开始获取 + start_fetch = latest + + df = pro.daily(ts_code=ts_code, start_date=start_fetch, end_date=end_date) + + if df is not None and len(df) > 0: + # 过滤掉已存在的数据 + df = df[df['trade_date'] > latest] + + if len(df) > 0: + # 合并到主文件 + if existing_df is not None: + combined = pd.concat([existing_df, df], ignore_index=True) + combined = combined.sort_values(['ts_code', 'trade_date']).reset_index(drop=True) + combined.to_parquet(main_file, index=False, compression='snappy') + existing_df = combined + else: + df.to_parquet(main_file, index=False, compression='snappy') + existing_df = df + + total_records += len(df) + print(f"[{i+1}/{total_stocks}] {ts_code} ✓ +{len(df)}条") + else: + print(f"[{i+1}/{total_stocks}] {ts_code} - 无新数据") + else: + print(f"[{i+1}/{total_stocks}] {ts_code} - 无数据") + + batch_count += 1 + + # 每批次保存一次,减少请求间隔 + if batch_count >= batch_size: + batch_count = 0 + + time.sleep(REQUEST_INTERVAL) + + except Exception as e: + print(f"[{i+1}/{total_stocks}] {ts_code} ✗ {str(e)[:50]}") + time.sleep(1) # 错误后多等一会 + + print("-" * 50) + print(f"增量更新完成,新增 {total_records} 条记录") + + return total_records + + +def check_missing_status(pro, days=30): + """检查缺失状态""" + print("=" * 60) + print("A股数据缺失状态检查") + print("=" * 60) + + # 获取现有数据最新日期 + latest_dates = get_latest_dates() + codes = get_all_stock_codes() + + print(f"已获取数据股票数: {len(codes)}") + + # 获取缺失信息 + missing_info, trade_dates = get_missing_dates(pro, latest_dates, codes, days) + + # 统计 + total_missing = len(missing_info) + if total_missing == 0: + print("\n✓ 所有股票数据都是最新的!") + return {} + + # 按缺失天数分组统计 + missing_stats = {} + for ts_code, info in missing_info.items(): + count = info['missing_count'] + if count not in missing_stats: + missing_stats[count] = 0 + missing_stats[count] += 1 + + print(f"\n需要更新的股票: {total_missing} 只") + print(f"最近交易日: {trade_dates[-5:] if len(trade_dates) >= 5 else trade_dates}") + + print("\n缺失天数分布:") + for days_count in sorted(missing_stats.keys()): + print(f" 缺{days_count}天: {missing_stats[days_count]} 只") + + # 显示缺失最多的股票 + print("\n缺失最多的10只股票:") + sorted_missing = sorted(missing_info.items(), key=lambda x: x[1]['missing_count'], reverse=True)[:10] + for ts_code, info in sorted_missing: + print(f" {ts_code}: 最新{info['latest']}, 缺{info['missing_count']}天") + + return missing_info + + +def main(): + parser = argparse.ArgumentParser(description='A股每日增量数据更新') + parser.add_argument('--check', action='store_true', help='只检查不更新') + parser.add_argument('--days', type=int, default=30, help='检查最近多少天') + args = parser.parse_args() + + print(f"运行时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") + + # 初始化 + pro = setup_tushare() + + if args.check: + # 只检查 + check_missing_status(pro, args.days) + else: + # 检查并更新 + missing_info = check_missing_status(pro, args.days) + if missing_info: + fetch_missing_data(pro, missing_info) + # 再次检查确认 + print("\n更新后再次检查...") + check_missing_status(pro, args.days) + + # 显示文件大小 + main_file = DATA_DIR / 'stock_daily_data.parquet' + if main_file.exists(): + size_mb = main_file.stat().st_size / 1024 / 1024 + print(f"\n数据文件大小: {size_mb:.2f} MB") + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/fetch_history.py b/fetch_history.py index 69486ba..25c347a 100644 --- a/fetch_history.py +++ b/fetch_history.py @@ -25,7 +25,7 @@ START_DATE = '20100101' END_DATE = datetime.now().strftime('%Y%m%d') # 请求间隔(秒)- tushare积分限制 -REQUEST_INTERVAL = 9 +REQUEST_INTERVAL = 5 def setup_tushare(token=None): @@ -91,34 +91,109 @@ def get_stock_codes_with_suffix(df): def fetch_daily_data(pro, codes, start_date, end_date): - """逐个获取日线数据(每次一支股票)""" - all_data = [] + """逐个获取日线数据(每次一支股票),支持断点续传""" total = len(codes) - print(f"\n共 {total} 只股票需要获取") - print(f"预计耗时: {total * REQUEST_INTERVAL / 60:.1f} 分钟") + # 加载已完成的股票列表 + completed_file = DATA_DIR / 'completed_stocks.txt' + completed_stocks = set() + if completed_file.exists(): + lines = completed_file.read_text().strip().split('\n') + completed_stocks = set(line.strip() for line in lines if line.strip()) + print(f"已完成: {len(completed_stocks)} 只股票") + + # 统计已有数据 + existing_data_file = DATA_DIR / 'stock_daily_data.parquet' + if existing_data_file.exists(): + existing_df = pd.read_parquet(existing_data_file) + print(f"已有数据: {len(existing_df)} 条记录") + + print(f"\n共 {total} 只股票,待处理: {total - len(completed_stocks)} 只") + print(f"预计耗时: {(total - len(completed_stocks)) * REQUEST_INTERVAL / 60:.1f} 分钟") print("-" * 50) for i, ts_code in enumerate(codes): + # 跳过已完成的 + if ts_code in completed_stocks: + print(f"[{i+1}/{total}] {ts_code} 已完成,跳过") + continue + try: - print(f"[{i+1}/{total}] 获取 {ts_code}...", end=' ') + print(f"[{i+1}/{total}] 获取 {ts_code}...", end=' ', flush=True) df = pro.daily(ts_code=ts_code, start_date=start_date, end_date=end_date) if df is not None and len(df) > 0: - all_data.append(df) print(f"成功,{len(df)} 条记录") + # 实时保存单只股票数据 + save_single_stock(df, ts_code, completed_file) else: print("无数据") + # 无数据也标记为完成 + mark_completed(ts_code, completed_file) except Exception as e: print(f"错误: {e}") + # 出错不标记完成,下次重试 - # 每次请求后休息9秒 - if i < total - 1: # 最后一个不需要等待 + # 每次请求后休息 + if i < total - 1: time.sleep(REQUEST_INTERVAL) - return all_data + # 最后合并所有数据 + return merge_all_data() + + +def save_single_stock(df, ts_code, completed_file): + """保存单只股票数据并标记完成""" + # 读取已有数据 + output_file = DATA_DIR / 'stock_daily_data.parquet' + + if output_file.exists(): + existing_df = pd.read_parquet(output_file) + # 删除该股票的旧数据(如果有) + existing_df = existing_df[existing_df['ts_code'] != ts_code] + # 合并新数据 + combined_df = pd.concat([existing_df, df], ignore_index=True) + else: + combined_df = df + + # 排序 + combined_df = combined_df.sort_values(['ts_code', 'trade_date']).reset_index(drop=True) + + # 保存 + combined_df.to_parquet(output_file, index=False) + + # 标记完成 + mark_completed(ts_code, completed_file) + + +def merge_all_data(): + """最后合并所有数据(用于返回)""" + output_file = DATA_DIR / 'stock_daily_data.parquet' + if output_file.exists(): + return [pd.read_parquet(output_file)] + return [] + + +def save_progress(all_data, ts_code, completed_file): + """实时保存进度(保留兼容性)""" + # 合并并保存数据 + combined_df = pd.concat(all_data, ignore_index=True) + combined_df = combined_df.sort_values(['ts_code', 'trade_date']).reset_index(drop=True) + + # 保存parquet + output_file = DATA_DIR / 'stock_daily_data.parquet' + combined_df.to_parquet(output_file, index=False) + + # 标记完成 + mark_completed(ts_code, completed_file) + + +def mark_completed(ts_code, completed_file): + """标记股票已完成""" + with open(completed_file, 'a') as f: + f.write(ts_code + '\n') def save_to_parquet(df, filename): @@ -197,4 +272,4 @@ def main(): if __name__ == '__main__': - main() \ No newline at end of file + main()