import config from DataAnalysis import DataExporter from base import LogHelper, Config from datetime import datetime from DataAnalysis import MarketDataCalculator from tqdm import tqdm from pathlib import Path from UpdateFutuData.updatekline import * from DataAnalysis.checktable import * # 导出数据 def exportMonthlyAvgData() -> bool: exporter = DataExporter(Config.ConfigInfo.db_hk_kline_1d) # 根据导出时间 -> 一般是当天计算,当天导出。(根据实际情况进行调整) target_table_name = 'hk_monthly_avg_' + datetime.now().strftime("%Y%m%d") target_file_name = 'hk_monthly_avg_' + datetime.now().strftime("%Y%m%d") + ".csv" return exporter.export_data( monthly_table = target_table_name, csv_file = target_file_name ) def calculate_update_monthly_avg_table() -> bool: calculator = MarketDataCalculator(Config.ConfigInfo.db_hk_kline_1d) try: # 移除人民币交易的股票:股票名称最后一个字符为R,误删除的从配置文件读回来 Reservedcode = calculator.read_stock_codes_list(Path.cwd().parent/"HKDataManagment" / "config"/"Reservedcode.txt") market_data_ll = calculator.get_stock_codes() # 使用按照价格和流通股数量筛选的那个表格 market_data = market_data_ll + Reservedcode # 根据统计时间进行命名 target_table_name = 'hk_monthly_avg_' + datetime.now().strftime("%Y%m%d") # 使用tqdm创建进度条 for code in tqdm(market_data, desc="处理股票数据", unit="支"): tablename = 'hk_' + code[3:] # 计算并保存月度均值 calculator.calculate_and_save_monthly_avg( source_table = tablename, target_table=target_table_name ) return True except Exception as e: # logger.error(f"更新月均流通市值失败: {str(e)}") return False if __name__ == "__main__": # # 应用配置 logger = LogHelper(logger_name = 'main').setup() # if True: # logger.info("开始统计月度均值") # success = calculate_update_monthly_avg_table() # if success: # logger.info("月度均值统计成功完成") # else: # logger.error("处理过程中出现错误") # if True: # logger.info("开始导出数据") # success = exportMonthlyAvgData() # if success: # logger.info("数据导出成功完成") # else: # logger.error("数据导出过程中出现错误") # 数据库配置 db_config = { 'host': 'localhost', 'user': 'root', 'password': 'bzskmysql', 'database': 'hk_kline_1d' } # 创建检查器并运行 checker = StockTableChecker(db_config) checker.run_check() futuStockFilter = FutuStockFilter(db_config) futuStockFilter.run_direct_import() # 创建导入器并运行, 用于每日更新流通股数量 -> 操作界面中增加一个开关,每天只需要更新一次 futuStockFilter = FutuStockFilter(db_config) futuStockFilter.run_direct_import() # 每个账号获取的数据独立开来 -> 操作见面可以选择 market_data_all = get_stock_codes() market_data_hang = read_single_account_stock_codes('config\hang_futu.txt') market_data_kevin= read_single_account_stock_codes('config\kevin_futu.txt') market_data_HK= read_single_account_stock_codes('config\HK_futu.txt') market_data_new = list(set(market_data_all) - set(market_data_hang) - set(market_data_kevin) - set(market_data_HK)) write_missing_codes_to_txt(market_data_new) # 新股票添加到文件中 -> 暂时手动设置 # 动态调整 """*********************************************""" market_data = read_single_account_stock_codes('config\missing_codes.txt') # 每天收盘后更新数据 -> 操作界面中,这个参数需要放出来 start_date = (datetime.now() - timedelta(days = 1)).strftime("%Y-%m-%d") end_date = (datetime.now() + timedelta(days = 1)).strftime("%Y-%m-%d") # 获取流通股数据字典 float_share_dict = get_float_share_data(db_config, 'stock_filter') # 假设数据在stock_filter表中 # 使用tqdm创建进度条 for code in tqdm(market_data, desc="下载股票数据", unit="支"): full_code = f"{code}" quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111) # 从字典中获取流通股数量 float_share = float_share_dict.get(code) if float_share_dict else None # 如果字典中没有找到,尝试从API获取 if float_share is None: float_share = get_float_share(quote_ctx, code) if float_share is not None: logger.info(f"从API获取股票 {code} 的流通股数量: {float_share}") else: logger.warning(f"无法获取股票 {code} 的流通股数量") # 获取历史K线数据 ret, data, page_req_key = quote_ctx.request_history_kline(code, start=start_date, end=end_date, max_count=100) # 保存数据到自定义表 custom_table_name = 'hk_' + code[3:] # 自定义表名 if ret == RET_OK: success = save_quotes_to_db(db_config, data, table_name=custom_table_name, float_share=float_share) else: logger.error(f'error:{data}') isWhile = False # 只返回一页时增加请求延迟 while page_req_key != None: # 请求后面的所有结果 isWhile = True ret, data, page_req_key = quote_ctx.request_history_kline(code, start=start_date, end=end_date, max_count=100, page_req_key=page_req_key) # 请求翻页后的数据 if ret == RET_OK: success = save_quotes_to_db(db_config, data, table_name=custom_table_name, float_share=float_share) else: logger.error(f'error:{ data}') time.sleep(0.7) if isWhile == False: time.sleep(0.7) quote_ctx.close() # 结束后记得关闭当条连接,防止连接条数用尽