2025-06-18 10:25:05 +08:00
|
|
|
|
{
|
|
|
|
|
|
"cells": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
"id": "initial_id",
|
|
|
|
|
|
"metadata": {
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"collapsed": true,
|
2025-06-18 10:25:05 +08:00
|
|
|
|
"ExecuteTime": {
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"end_time": "2025-06-23T14:21:43.971470Z",
|
|
|
|
|
|
"start_time": "2025-06-23T14:21:43.591298Z"
|
2025-06-18 10:25:05 +08:00
|
|
|
|
}
|
2025-06-22 23:03:50 +08:00
|
|
|
|
},
|
2025-06-18 10:25:05 +08:00
|
|
|
|
"source": [
|
|
|
|
|
|
"%load_ext autoreload\n",
|
|
|
|
|
|
"%autoreload 2\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"from src.analysis.result_analyzer import ResultAnalyzer\n",
|
|
|
|
|
|
"# 导入所有必要的模块\n",
|
|
|
|
|
|
"from src.data_manager import DataManager\n",
|
|
|
|
|
|
"from src.backtest_engine import BacktestEngine\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"from src.strategies.simple_limit_buy_strategy import SimpleLimitBuyStrategy\n",
|
2025-06-18 10:25:05 +08:00
|
|
|
|
"\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"def main():\n",
|
|
|
|
|
|
" # --- 配置参数 ---\n",
|
|
|
|
|
|
" # 获取当前脚本所在目录,假设数据文件在项目根目录下的 data 文件夹内\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
" # data_file_path = '/mnt/d/PyProject/NewQuant/data/data/SHFE_rb2510/SHFE_rb2510_min60.csv'\n",
|
|
|
|
|
|
" data_file_path = \"/mnt/d/PyProject/NewQuant/data/data/KQ_m@SHFE_rb/KQ_m@SHFE_rb_min60.csv\"\n",
|
2025-06-18 10:25:05 +08:00
|
|
|
|
"\n",
|
|
|
|
|
|
" initial_capital = 100000.0\n",
|
2025-06-22 23:03:50 +08:00
|
|
|
|
" slippage_rate = 0.000 # 假设每笔交易0.1%的滑点\n",
|
2025-06-18 10:25:05 +08:00
|
|
|
|
" commission_rate = 0.0002 # 假设每笔交易0.02%的佣金\n",
|
|
|
|
|
|
"\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
" global_config = {\n",
|
|
|
|
|
|
" 'symbol': 'KQ_m@SHFE_rb',\n",
|
|
|
|
|
|
" }\n",
|
|
|
|
|
|
"\n",
|
2025-06-18 10:25:05 +08:00
|
|
|
|
" strategy_parameters = {\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
" # 'symbol': \"SHFE_rb2501\", # 根据您的数据文件中的品种名称调整\n",
|
2025-06-22 23:03:50 +08:00
|
|
|
|
" 'trade_volume': 20,\n",
|
|
|
|
|
|
" 'open_range_factor_1_ago': 1.7, # 示例值,需要通过网格搜索优化\n",
|
|
|
|
|
|
" 'open_range_factor_7_ago': -1.8, # 示例值\n",
|
|
|
|
|
|
" 'max_position': 10,\n",
|
|
|
|
|
|
" 'enable_log': True\n",
|
2025-06-18 10:25:05 +08:00
|
|
|
|
" }\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
" # --- 1. 初始化数据管理器 ---\n",
|
|
|
|
|
|
" print(\"初始化数据管理器...\")\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
" data_manager = DataManager(file_path=data_file_path, symbol=global_config['symbol'])\n",
|
2025-06-18 10:25:05 +08:00
|
|
|
|
" # 确保 DataManager 能够重置以进行多次回测\n",
|
|
|
|
|
|
" # data_manager.reset() # 首次运行不需要重置\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
" # --- 2. 初始化回测引擎并运行 ---\n",
|
|
|
|
|
|
" print(\"\\n初始化回测引擎...\")\n",
|
|
|
|
|
|
" engine = BacktestEngine(\n",
|
|
|
|
|
|
" data_manager=data_manager,\n",
|
|
|
|
|
|
" strategy_class=SimpleLimitBuyStrategy,\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
" # current_segment_symbol=strategy_parameters['symbol'],\n",
|
2025-06-18 10:25:05 +08:00
|
|
|
|
" strategy_params=strategy_parameters,\n",
|
|
|
|
|
|
" initial_capital=initial_capital,\n",
|
|
|
|
|
|
" slippage_rate=slippage_rate,\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
" commission_rate=commission_rate,\n",
|
|
|
|
|
|
" roll_over_mode=True\n",
|
2025-06-18 10:25:05 +08:00
|
|
|
|
" )\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
" print(\"\\n开始运行回测...\")\n",
|
|
|
|
|
|
" engine.run_backtest()\n",
|
|
|
|
|
|
" print(\"\\n回测运行完毕。\")\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
" # --- 3. 获取回测结果 ---\n",
|
|
|
|
|
|
" results = engine.get_backtest_results()\n",
|
|
|
|
|
|
" portfolio_snapshots = results[\"portfolio_snapshots\"]\n",
|
|
|
|
|
|
" trade_history = results[\"trade_history\"]\n",
|
|
|
|
|
|
" initial_capital_result = results[\"initial_capital\"]\n",
|
|
|
|
|
|
" bars = results[\"all_bars\"]\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
" # --- 4. 结果分析与可视化 ---\n",
|
|
|
|
|
|
" if portfolio_snapshots:\n",
|
|
|
|
|
|
" analyzer = ResultAnalyzer(portfolio_snapshots, trade_history, bars, initial_capital_result)\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
" analyzer.generate_report()\n",
|
|
|
|
|
|
" analyzer.plot_performance()\n",
|
|
|
|
|
|
" else:\n",
|
|
|
|
|
|
" print(\"\\n没有生成投资组合快照,无法进行结果分析。\")\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
" # --- 4. 结果分析与可视化 (待实现) ---\n",
|
|
|
|
|
|
" # if portfolio_snapshots:\n",
|
|
|
|
|
|
" # analyzer = ResultAnalyzer(portfolio_snapshots, trade_history, initial_capital_result)\n",
|
|
|
|
|
|
" # metrics = analyzer.calculate_all_metrics()\n",
|
|
|
|
|
|
" # print(\"\\n--- 绩效指标 ---\")\n",
|
|
|
|
|
|
" # for key, value in metrics.items():\n",
|
|
|
|
|
|
" # print(f\" {key}: {value:.4f}\")\n",
|
|
|
|
|
|
" #\n",
|
|
|
|
|
|
" # print(\"\\n--- 绘制绩效图表 ---\")\n",
|
|
|
|
|
|
" # analyzer.plot_performance()\n",
|
|
|
|
|
|
" # else:\n",
|
|
|
|
|
|
" # print(\"\\n没有生成投资组合快照,无法进行结果分析。\")\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"if __name__ == '__main__':\n",
|
|
|
|
|
|
" main()\n"
|
2025-06-22 23:03:50 +08:00
|
|
|
|
],
|
|
|
|
|
|
"outputs": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "stdout",
|
|
|
|
|
|
"output_type": "stream",
|
|
|
|
|
|
"text": [
|
|
|
|
|
|
"The autoreload extension is already loaded. To reload it, use:\n",
|
|
|
|
|
|
" %reload_ext autoreload\n",
|
|
|
|
|
|
"初始化数据管理器...\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"数据加载成功: /mnt/d/PyProject/NewQuant/data/data/KQ_m@SHFE_rb/KQ_m@SHFE_rb_min60.csv\n",
|
|
|
|
|
|
"数据范围从 2022-12-30 14:00:00 到 2025-06-20 21:00:00\n",
|
|
|
|
|
|
"总计 4131 条记录。\n",
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"\n",
|
|
|
|
|
|
"初始化回测引擎...\n",
|
|
|
|
|
|
"模拟器初始化:初始资金=100000.00, 滑点率=0.0, 佣金率=0.0002\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"--- 回测引擎初始化完成 ---\n",
|
|
|
|
|
|
" 策略: SimpleLimitBuyStrategy\n",
|
|
|
|
|
|
" 初始资金: 100000.00\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
" 换月模式: 启用\n",
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"\n",
|
|
|
|
|
|
"开始运行回测...\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"--- 回测开始 ---\n",
|
|
|
|
|
|
"SimpleLimitBuyStrategy 策略初始化回调被调用。\n",
|
|
|
|
|
|
"开始将 DataFrame 转换为 Bar 对象流...\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
" open high low close volume open_oi \\\n",
|
|
|
|
|
|
"datetime \n",
|
|
|
|
|
|
"2022-12-30 14:00:00 4119.0 4125.0 4095.0 4105.0 307021.0 1954149.0 \n",
|
|
|
|
|
|
"2023-01-03 09:00:00 4090.0 4100.0 4016.0 4037.0 741293.0 1931845.0 \n",
|
|
|
|
|
|
"2023-01-03 10:00:00 4037.0 4056.0 4037.0 4043.0 158816.0 1883537.0 \n",
|
|
|
|
|
|
"2023-01-03 11:00:00 4043.0 4054.0 4037.0 4051.0 67599.0 1887716.0 \n",
|
|
|
|
|
|
"2023-01-03 13:00:00 4055.0 4065.0 4045.0 4058.0 110044.0 1890125.0 \n",
|
|
|
|
|
|
"... ... ... ... ... ... ... \n",
|
|
|
|
|
|
"2025-06-20 10:00:00 3003.0 3010.0 2998.0 3002.0 270615.0 2186077.0 \n",
|
|
|
|
|
|
"2025-06-20 11:00:00 3002.0 3002.0 2986.0 2991.0 170375.0 2204438.0 \n",
|
|
|
|
|
|
"2025-06-20 13:00:00 2992.0 2997.0 2990.0 2991.0 87875.0 2173829.0 \n",
|
|
|
|
|
|
"2025-06-20 14:00:00 2991.0 2994.0 2987.0 2992.0 174940.0 2170066.0 \n",
|
|
|
|
|
|
"2025-06-20 21:00:00 2990.0 2993.0 2983.0 2990.0 197096.0 2164155.0 \n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
" close_oi underlying_symbol \n",
|
|
|
|
|
|
"datetime \n",
|
|
|
|
|
|
"2022-12-30 14:00:00 1931845.0 SHFE.rb2305 \n",
|
|
|
|
|
|
"2023-01-03 09:00:00 1883537.0 SHFE.rb2305 \n",
|
|
|
|
|
|
"2023-01-03 10:00:00 1887716.0 SHFE.rb2305 \n",
|
|
|
|
|
|
"2023-01-03 11:00:00 1890125.0 SHFE.rb2305 \n",
|
|
|
|
|
|
"2023-01-03 13:00:00 1895898.0 SHFE.rb2305 \n",
|
|
|
|
|
|
"... ... ... \n",
|
|
|
|
|
|
"2025-06-20 10:00:00 2204438.0 SHFE.rb2510 \n",
|
|
|
|
|
|
"2025-06-20 11:00:00 2173829.0 SHFE.rb2510 \n",
|
|
|
|
|
|
"2025-06-20 13:00:00 2170066.0 SHFE.rb2510 \n",
|
|
|
|
|
|
"2025-06-20 14:00:00 2164155.0 SHFE.rb2510 \n",
|
|
|
|
|
|
"2025-06-20 21:00:00 2169073.0 SHFE.rb2510 \n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"[4131 rows x 8 columns]\n",
|
|
|
|
|
|
"True None SHFE.rb2305 None\n",
|
|
|
|
|
|
"[2022-12-30 14:00:00]发送订单 SHFE.rb2305_BUY_20221230140000_0, direction BUY\n",
|
|
|
|
|
|
"True SHFE.rb2305 SHFE.rb2310 SHFE.rb2305\n",
|
|
|
|
|
|
"[2023-04-03 13:00:00] 策略 (SHFE.rb2305): 检测到换月!从 [SHFE.rb2305] 切换到 [SHFE.rb2310]。在旧合约最后一根K线 (2023-04-03 13:00:00) 执行强制平仓和取消操作。\n",
|
|
|
|
|
|
"[2023-04-03 13:00:00] 策略 (SHFE.rb2305): 合约换月事件: 从 SHFE.rb2305 切换到 SHFE.rb2310\n",
|
|
|
|
|
|
"[2023-04-03 14:00:00] 策略 (SHFE.rb2310): 当前是换月K线,禁止开仓订单\n",
|
|
|
|
|
|
"[2023-04-03 21:00:00]发送订单 SHFE.rb2310_BUY_20230403210000_2, direction BUY\n",
|
|
|
|
|
|
"True SHFE.rb2310 SHFE.rb2401 SHFE.rb2310\n",
|
|
|
|
|
|
"[2023-09-04 13:00:00] 策略 (SHFE.rb2310): 检测到换月!从 [SHFE.rb2310] 切换到 [SHFE.rb2401]。在旧合约最后一根K线 (2023-09-04 13:00:00) 执行强制平仓和取消操作。\n",
|
|
|
|
|
|
"[2023-09-04 13:00:00] 策略 (SHFE.rb2310): 合约换月事件: 从 SHFE.rb2310 切换到 SHFE.rb2401\n",
|
|
|
|
|
|
"[2023-09-04 14:00:00] 策略 (SHFE.rb2401): 当前是换月K线,禁止开仓订单\n",
|
|
|
|
|
|
"[2023-09-04 21:00:00]发送订单 SHFE.rb2401_BUY_20230904210000_4, direction BUY\n",
|
|
|
|
|
|
"True SHFE.rb2401 SHFE.rb2405 SHFE.rb2401\n",
|
|
|
|
|
|
"[2023-12-06 13:00:00] 策略 (SHFE.rb2401): 检测到换月!从 [SHFE.rb2401] 切换到 [SHFE.rb2405]。在旧合约最后一根K线 (2023-12-06 13:00:00) 执行强制平仓和取消操作。\n",
|
|
|
|
|
|
"[2023-12-06 13:00:00] 策略 (SHFE.rb2401): 合约换月事件: 从 SHFE.rb2401 切换到 SHFE.rb2405\n",
|
|
|
|
|
|
"[2023-12-06 14:00:00] 策略 (SHFE.rb2405): 当前是换月K线,禁止开仓订单\n",
|
|
|
|
|
|
"[2023-12-06 21:00:00]发送订单 SHFE.rb2405_BUY_20231206210000_6, direction BUY\n",
|
|
|
|
|
|
"True SHFE.rb2405 SHFE.rb2410 SHFE.rb2405\n",
|
|
|
|
|
|
"[2024-04-01 13:00:00] 策略 (SHFE.rb2405): 检测到换月!从 [SHFE.rb2405] 切换到 [SHFE.rb2410]。在旧合约最后一根K线 (2024-04-01 13:00:00) 执行强制平仓和取消操作。\n",
|
|
|
|
|
|
"[2024-04-01 13:00:00] 策略 (SHFE.rb2405): 合约换月事件: 从 SHFE.rb2405 切换到 SHFE.rb2410\n",
|
|
|
|
|
|
"[2024-04-01 14:00:00] 策略 (SHFE.rb2410): 当前是换月K线,禁止开仓订单\n",
|
|
|
|
|
|
"[2024-04-01 21:00:00]发送订单 SHFE.rb2410_BUY_20240401210000_8, direction BUY\n",
|
|
|
|
|
|
"True SHFE.rb2410 SHFE.rb2501 SHFE.rb2410\n",
|
|
|
|
|
|
"[2024-08-30 13:00:00] 策略 (SHFE.rb2410): 检测到换月!从 [SHFE.rb2410] 切换到 [SHFE.rb2501]。在旧合约最后一根K线 (2024-08-30 13:00:00) 执行强制平仓和取消操作。\n",
|
|
|
|
|
|
"[2024-08-30 13:00:00] 策略 (SHFE.rb2410): 合约换月事件: 从 SHFE.rb2410 切换到 SHFE.rb2501\n",
|
|
|
|
|
|
"[2024-08-30 14:00:00] 策略 (SHFE.rb2501): 当前是换月K线,禁止开仓订单\n",
|
|
|
|
|
|
"[2024-08-30 21:00:00]发送订单 SHFE.rb2501_BUY_20240830210000_10, direction BUY\n",
|
|
|
|
|
|
"True SHFE.rb2501 SHFE.rb2505 SHFE.rb2501\n",
|
|
|
|
|
|
"[2024-12-05 13:00:00] 策略 (SHFE.rb2501): 检测到换月!从 [SHFE.rb2501] 切换到 [SHFE.rb2505]。在旧合约最后一根K线 (2024-12-05 13:00:00) 执行强制平仓和取消操作。\n",
|
|
|
|
|
|
"[2024-12-05 13:00:00] 策略 (SHFE.rb2501): 合约换月事件: 从 SHFE.rb2501 切换到 SHFE.rb2505\n",
|
|
|
|
|
|
"[2024-12-05 14:00:00] 策略 (SHFE.rb2505): 当前是换月K线,禁止开仓订单\n",
|
|
|
|
|
|
"[2024-12-05 21:00:00]发送订单 SHFE.rb2505_BUY_20241205210000_12, direction BUY\n",
|
|
|
|
|
|
"True SHFE.rb2505 SHFE.rb2510 SHFE.rb2505\n",
|
|
|
|
|
|
"[2025-04-07 13:00:00] 策略 (SHFE.rb2505): 检测到换月!从 [SHFE.rb2505] 切换到 [SHFE.rb2510]。在旧合约最后一根K线 (2025-04-07 13:00:00) 执行强制平仓和取消操作。\n",
|
|
|
|
|
|
"[2025-04-07 13:00:00] 策略 (SHFE.rb2505): 合约换月事件: 从 SHFE.rb2505 切换到 SHFE.rb2510\n",
|
|
|
|
|
|
"[2025-04-07 14:00:00] 策略 (SHFE.rb2510): 当前是换月K线,禁止开仓订单\n",
|
|
|
|
|
|
"[2025-04-07 21:00:00]发送订单 SHFE.rb2510_BUY_20250407210000_14, direction BUY\n",
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"Bar 对象流生成完毕。\n",
|
|
|
|
|
|
"\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"--- 回测结束,检查并平仓所有剩余持仓 ---\n",
|
|
|
|
|
|
"[2025-06-20 21:00:00] 策略 (SHFE.rb2510): 回测结束清理: 强制平仓合约 SHFE.rb2510 的剩余持仓。\n",
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"--- 回测结束 ---\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"总计处理了 4131 根K线。\n",
|
|
|
|
|
|
"总计发生了 16 笔交易。\n",
|
|
|
|
|
|
"最终总净值: 98545.60\n",
|
|
|
|
|
|
"总收益率: -1.45%\n",
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"\n",
|
|
|
|
|
|
"回测运行完毕。\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"--- 结果分析器初始化完成 ---\n",
|
|
|
|
|
|
"正在计算绩效指标...\n",
|
|
|
|
|
|
"绩效指标计算完成。\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"--- 回测绩效报告 ---\n",
|
|
|
|
|
|
"初始资金 : 100000.00\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"最终资金 : 98546.19\n",
|
|
|
|
|
|
"总收益率 : -1.45%\n",
|
|
|
|
|
|
"年化收益率 : -0.41%\n",
|
|
|
|
|
|
"最大回撤 : 1.80%\n",
|
|
|
|
|
|
"夏普比率 : -0.37\n",
|
|
|
|
|
|
"卡玛比率 : -0.23\n",
|
|
|
|
|
|
"总交易次数 : 16\n",
|
|
|
|
|
|
"总实现盈亏 : 0.00\n",
|
|
|
|
|
|
"交易成本 : 11.40\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"--- 交易详情 ---\n",
|
|
|
|
|
|
"盈利交易次数 : 0\n",
|
|
|
|
|
|
"亏损交易次数 : 0\n",
|
|
|
|
|
|
"胜率 : 0.00%\n",
|
|
|
|
|
|
"盈亏比 : inf\n",
|
|
|
|
|
|
"平均每次盈利 : 0.00\n",
|
|
|
|
|
|
"平均每次亏损 : 0.00\n",
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"\n",
|
|
|
|
|
|
"--- 部分交易明细 (最近5笔) ---\n",
|
2025-06-23 22:21:59 +08:00
|
|
|
|
" 2024-12-05 13:00:00 | SELL | SHFE.rb2501 | Vol: 1 | Price: 3295.00 | Comm: 0.66\n",
|
|
|
|
|
|
" 2024-12-05 22:00:00 | BUY | SHFE.rb2505 | Vol: 1 | Price: 3330.00 | Comm: 0.67\n",
|
|
|
|
|
|
" 2025-04-07 13:00:00 | SELL | SHFE.rb2505 | Vol: 1 | Price: 3094.00 | Comm: 0.62\n",
|
|
|
|
|
|
" 2025-04-07 22:00:00 | BUY | SHFE.rb2510 | Vol: 1 | Price: 3158.00 | Comm: 0.63\n",
|
|
|
|
|
|
" 2025-06-20 21:00:00 | SELL | SHFE.rb2510 | Vol: 1 | Price: 2990.00 | Comm: 0.60\n",
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"正在绘制绩效图表...\n"
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
"text/plain": [
|
|
|
|
|
|
"<Figure size 1400x1000 with 2 Axes>"
|
|
|
|
|
|
],
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAABWUAAAPdCAYAAADiWgoIAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Xd4U+X7BvA7SdN0QqFlLwFtwVL2kCVbhgMBERSQIYIoIOpPBUUEUUFEREScKEMU+DJUpiBL9h6yt7LpoNDdjPP743iSc5KTNGnTNmnvz3Vx0SYnyZuTN6ftnec8r0YQBAFEREREREREREREVCC0hT0AIiIiIiIiIiIiouKEoSwRERERERERERFRAWIoS0RERERERERERFSAGMoSERERERERERERFSCGskREREREREREREQFiKEsERERERERERERUQFiKEtERERERERERERUgBjKEhERERERERERERUghrJEREREREREREREBYihLBERFRnt27dHTEyM4l+dOnXQtm1bjBkzBgcOHCjsITo4f/48XnrpJTRv3hy1a9dGTEwMvvjii1zf39WrVxETE4P27ds7XCftn6tXr+ZlyG5Rey3U/q1YsSLfx+LK2LFjfWIcvig3+2bFihWq78FmzZqhW7dueP3117FkyRKkpqbm48gLn6v3YVG3c+dOjBs3Dp07d0bDhg1Rp04dtGrVCoMHD8a8efOQlJRU2EMsVPPnz0dMTAz++OMPl9v9+OOP1vfQwoULXW67d+9exMTEYMCAAQ7XSfeRWxcuXMCUKVPw5JNPolmzZoiNjUWzZs3Qp08ffPrpp7hw4UKu75vy7sCBA4iJicG0adMKeyhERJQLAYU9ACIiIm9r2LAhqlWrBgC4d+8ejh8/jnXr1mH9+vV46623MHjw4Hwfw4oVKzBu3Dj06NEDU6dOVd0mPT0dw4YNw7Vr16zBhU6nQ+3atfN9fAVF/lqoqVq1agGOxn3uvH7kXEhICDp37gwAsFgsSElJwdWrV7F27VqsXr0aU6dOxauvvooBAwZAo9EU8mjJG5KSkvD6669j165dAIBKlSqhWbNmCAkJQXx8PA4fPoxdu3bh888/x7x581CvXr1CHnHBS0pKwuzZsxEXF2d9fzizbNky69fLly9XDVzzk8lkwrRp07Bw4UJYLBZERESgTp06iIiIQEpKCk6cOIEj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
|
2025-06-22 23:03:50 +08:00
|
|
|
|
},
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
"output_type": "display_data"
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
"text/plain": [
|
|
|
|
|
|
"<Figure size 1400x700 with 1 Axes>"
|
|
|
|
|
|
],
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAABW0AAAKyCAYAAACuWPzHAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Xd4FNX6B/DvzO6mbHqjV4Ek9CJVUBREbPwELFgAGwoqdrF3QdFrQQHrBRTEiwWwgvcKIoL0Jh0JNfQU0suWmd8fuzs7szubbJJNskm+n+fxcefMmZmzm7Mb8u477xFkWZZBREREREREREREREFBrO0BEBEREREREREREZEbg7ZEREREREREREREQYRBWyIiIiIiIiIiIqIgwqAtERERERERERERURBh0JaIiIiIiIiIiIgoiDBoS0RERERERERERBREGLQlIiIiIiIiIiIiCiIM2hIREREREREREREFEQZtiYiIiIiIiIiIiIIIg7ZERNSgnThxAikpKUhJScGJEyfK7DtkyBCkpKRgyZIlNTK2mTNnIiUlBTNnzqyR6wX6mq7XdsiQIQEYWc2ZN2+eMicWLFhQ28OpVadPn8Z7772Hm266Cf3790fnzp3Ru3dvjBo1ClOnTsXOnTu9jnG9dvXFuHHjlOfk+q9Lly4YNGgQJk2ahN9//71S562N93dlvP7660hNTcWuXbt89jl06BDeeOMNjBw5Ev369UPnzp3Rr18/jBkzBu+88w4OHTpUgyOmuqwynx9679GUlBR0794dV111FV577TWcOnWqmkYcGOnp6ejSpQsefvjh2h4KEREFEQZtiYiIiFS+++475fHixYtrcSSVs2TJEqSkpODpp5+u0nk+++wzDBs2DB9//DEOHjyI1NRUXHnllejduzdyc3OxYMEC3HjjjXjrrbcCNPLglpqailGjRmHUqFEYMmQIwsLCsGrVKtx3332YOnVqbQ+vWhw6dAgLFy7EFVdcga5du3rtt9lseP3113Httdfi888/x+nTp9GlSxdceeWV6N69O06cOIFPP/0U1157Lb788staeAY1q64E4ssTqM+QmqZ+j44cORK9e/dGZmYmvvzyS4wYMUL3S6Zg0bJlS9x000349ddfsWnTptoeDhERBQljbQ+AiIiI6qfGjRtj2bJlMJlMtT0Uv+3YsQNpaWmIjo6GzWbDvn37sGfPHnTu3Lm2h1aj3n77bXz22WcwmUx46qmnMHbsWISEhGj67NixA++99x6OHj1aO4OsYZdffjkefPBBZVuSJMyYMQOffPIJFixYgKFDh2LAgAF+n++2227D1Vdfjbi4uOoYbkC89dZbsNlsmuetNmXKFCxbtgyRkZF47rnncN1118FgMCj7ZVnGX3/9hXfffRfHjh2rqWFTA+X5HgWA/Px8TJo0CVu2bMHLL79cY3fKVMZ9992Hb775Bm+88QaWLl1a28MhIqIgwExbIiIiqhYmkwnt2rVDq1atansofnNl2V5zzTW48sorNW0Nxfr16/HZZ58BAN577z3cddddXgFbAOjRowc+//xz3HXXXTU9xKAgiiIefvhhtGzZEgCwfPnyCh0fHx+Pdu3aIT4+vjqGV2VHjhzB6tWr0aNHD3To0MFr/3fffad8KTN37lyMHj1aE7AFAEEQMGjQIHz99de4+uqra2roRIqoqCg88MADAIA9e/YgPz+/lkfkW1JSEi655BLs3bsXmzdvru3hEBFREGCmLRERURWNGzcOmzZtwvz58xEdHY3Zs2dj8+bNKCwsRKtWrXDDDTfgzjvvhCAIXseWlJTgs88+w08//YRTp04hNjYWAwcO9Kuu3e7duzFv3jxs3boVmZmZMJvN6Nq1K8aPH4/Bgwd79R8yZAhOnjyJlStXYv/+/Zg/fz7279+P3NxczJ8/H/369dO9zgcffIDZs2djzJgxePXVV3X77Ny5EzfeeCMaNWqEVatWwWg04sSJExg6dCiaN2/uVffTVbPwwIED+O9//4vPP/8cBw4cgCRJSE1NxX333af7HADg5MmTmDlzJtasWYO8vDw0bdoU1157LSZOnIgJEyYoPwtfz8eXoqIiLFu2DABwww03oKSkBEuWLMHPP/+Mp59+GqGhobrHLV++HF9//TX27duHgoICREZGIiEhAb169cLYsWORmpqq9M3Pz8e///1v/P7770hPT4fNZkNsbCxatGiBAQMG4P777/fKTM7NzcUXX3yBlStX4vjx45AkCa1atcJVV12FO++8E+Hh4Upf188YAJYuXarJ1urbt69fNXo//PBD5VzDhg0rs68gCOjdu3e553TJycnB3LlzsXLlSpw4cQKiKKJt27a46qqrMG7cOISFhXkds27dOsyfPx87d+5Ebm4uzGYz4uLi0K1bN4wZMwZ9+vTxOmb9+vVYuHAhduzYgZycHERFRaFXr16YMGECevbs6fd4y2MwGNCxY0ekp6crrzvg33tt5syZmDVrFiZPnqybyXrkyBF88cUXWL9+Pc6cOQODwYAmTZqgb9++uPXWW5GcnKzpX5F54o+FCxdClmWMGjXKa58sy/j4448BADfffDO6d+9e5rlMJpPu675z507MmTMHW7duVX5O3bt3x7hx4zBw4ECv/k8//TSWLl2KN954A3369MEHH3yAdevWITc3F02aNME111yDBx54QPdLBsDxmblgwQJs3rwZGRkZCA8PR5MmTTBw4ECMHTsWzZs3V/r+73//w+rVq/H333/j7NmzKCkpQVJSEvr164d77rkHF1xwgebc6jqss2bNwqxZs5TtUaNGYfr06cq2zWbD0qVL8eOPP+LAgQMoKipCo0aNcPHFF2PSpElo2rSp5twbN27E+PHj0bdvX8ydOxfz5s3DDz/8gPT0dISHh6NPnz549NFH0a5dO6/nvG7dOqxcuRJbtmzBmTNnUFhYiPj4ePTq1Qt33XUXunXrpulf0c+QX3/9Fd9++y327NmDgoICxMXFoV+/fpg0aRLat2+v+3PYvn07Zs+ejR07dsBut6Nt27a49dZbccMNN+j2r6rExETlsc1m0+zLzs7Gzz//jDVr1uDQoUPIzMyE0WhEmzZtcOWVV+L222/X/exX/w5bvHgxvvnmG6SlpaGgoAArV65EixYtKvV5P3r0aKxcuRILFy7U/WwjIqKGhUFbIiKiAFm7di3mzZuHVq1aYeDAgcjIyMDWrVvx5ptv4vTp03juuec0/YuLi3HHHXdgx44dMJvNGDRoEEJDQ7F27Vr88ccfuPTSS31e64svvsD06dMhSRI6duyIbt26ITMzExs3bsTatWvx4IMPYvLkybrHzps3D19++SW6dOmCiy++GOfOnfPKkFO75ZZb8Omnn+Knn37CE088gejoaK8+CxcuBACMGTMGRqP//7z44IMP8OGHH6Jnz54YPHgwDh8+jO3bt2PixImYOXOmV9AwLS0NY8eOxfnz59GoUSMMHToUxcXFmDdvHjZs2ABJkvy+tqdly5ahsLBQWWgKANq0aYOjR4/if//7H0aMGOF1zKxZszBz5kwYjUb07NkTjRs3Rn5+Pk6fPo3vvvsO7du3V4K2xcXFuPXWW/HPP/8gPj4e/fv3h9lsRkZGBo4cOYIPP/wQd955p+aP+LS0NEyYMAGnT59GUlISLrzwQhiNRuzatQvvv/8+/ve//2HBggWIiooCAAwfPhw7duzAtm3b0KpVK1x44YXKuTyDTHry8vKwZcsWANAN1lVFeno6br/9dpw8eRLx8fEYPHgwrFYrNm7ciLfffhvLly/HvHnzEBMToxyzdOlSPPPMMwCAbt26oV+/figpKcHZs2exbNkyxMXFeQU23nzzTcydOxeiKKJLly648MILcfr0aaxcuRKrVq3Ca6+9huuvvz5gz6ugoAAAdAOFFX2vufz000949tlnYbFY0KxZMwwePBiSJCE9PR2LFi1CQkKCJmhb0Xnij5UrVwIALrroIq99Bw4cQHp6OoDKz5NvvvkGL730EiRJQqdOndCvXz+cPHkSq1atwqpVq8r8DNu3bx+mTZuGmJgY9OnTB7m5udi2bRs+/vhjpKWlYfb
|
2025-06-22 23:03:50 +08:00
|
|
|
|
},
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
"output_type": "display_data"
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "stdout",
|
|
|
|
|
|
"output_type": "stream",
|
|
|
|
|
|
"text": [
|
|
|
|
|
|
"图表绘制完成。\n"
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"execution_count": 45
|
2025-06-18 10:25:05 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
"id": "9dd93e564f0e2b55",
|
|
|
|
|
|
"metadata": {
|
|
|
|
|
|
"ExecuteTime": {
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"end_time": "2025-06-23T14:21:44.026610Z",
|
|
|
|
|
|
"start_time": "2025-06-23T14:21:44.003545Z"
|
2025-06-18 10:25:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"source": [
|
|
|
|
|
|
"from matplotlib.font_manager import findfont, FontProperties\n",
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
"font = findfont(FontProperties(family=['SimHei']))\n",
|
|
|
|
|
|
"font"
|
|
|
|
|
|
],
|
2025-06-18 10:25:05 +08:00
|
|
|
|
"outputs": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
"text/plain": [
|
|
|
|
|
|
"'/home/liaozhaorun/.fonts/simhei.ttf'"
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"execution_count": 46,
|
2025-06-18 10:25:05 +08:00
|
|
|
|
"metadata": {},
|
|
|
|
|
|
"output_type": "execute_result"
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"execution_count": 46
|
2025-06-18 10:25:05 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
"id": "a14196c49af33461",
|
|
|
|
|
|
"metadata": {
|
|
|
|
|
|
"ExecuteTime": {
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"end_time": "2025-06-23T14:21:44.057984Z",
|
|
|
|
|
|
"start_time": "2025-06-23T14:21:44.041633Z"
|
2025-06-18 10:25:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
2025-06-22 23:03:50 +08:00
|
|
|
|
"source": [
|
|
|
|
|
|
"import matplotlib as mpl\n",
|
|
|
|
|
|
"print(mpl.rcParams['font.family'])"
|
|
|
|
|
|
],
|
2025-06-18 10:25:05 +08:00
|
|
|
|
"outputs": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"name": "stdout",
|
|
|
|
|
|
"output_type": "stream",
|
|
|
|
|
|
"text": [
|
|
|
|
|
|
"['sans-serif']\n"
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
2025-06-23 22:21:59 +08:00
|
|
|
|
"execution_count": 47
|
2025-06-18 10:25:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
],
|
|
|
|
|
|
"metadata": {
|
|
|
|
|
|
"kernelspec": {
|
|
|
|
|
|
"display_name": "quant",
|
|
|
|
|
|
"language": "python",
|
|
|
|
|
|
"name": "python3"
|
|
|
|
|
|
},
|
|
|
|
|
|
"language_info": {
|
|
|
|
|
|
"codemirror_mode": {
|
|
|
|
|
|
"name": "ipython",
|
|
|
|
|
|
"version": 3
|
|
|
|
|
|
},
|
|
|
|
|
|
"file_extension": ".py",
|
|
|
|
|
|
"mimetype": "text/x-python",
|
|
|
|
|
|
"name": "python",
|
|
|
|
|
|
"nbconvert_exporter": "python",
|
|
|
|
|
|
"pygments_lexer": "ipython3",
|
|
|
|
|
|
"version": "3.12.11"
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
"nbformat": 4,
|
|
|
|
|
|
"nbformat_minor": 5
|
|
|
|
|
|
}
|