erwin 1 ماه پیش
والد
کامیت
b81ad71d0d
100فایلهای تغییر یافته به همراه13 افزوده شده و 87155 حذف شده
  1. 5 1
      .claude/settings.local.json
  2. 0 321
      a50-futures/A50_futures_30min_20260305.csv
  3. 0 347
      a50-futures/fetch_a50_data.py
  4. 0 274
      a50-futures/fetch_a50_v2.py
  5. 0 166
      backtest.py
  6. 0 245
      backtest_historical.py
  7. 0 372
      backtest_real.py
  8. 0 32
      backtest_results/forward_test_20260317_133627.txt
  9. 0 29
      backtest_results/optimized_20260312_163559.txt
  10. 0 29
      backtest_results/optimized_20260312_164006.txt
  11. 0 29
      backtest_results/optimized_v2_20260312_170726.txt
  12. 0 29
      backtest_results/real_data_20260312_141816.txt
  13. 0 29
      backtest_results/real_data_20260312_141900.txt
  14. 0 29
      backtest_results/real_data_20260312_142026.txt
  15. 0 29
      backtest_results/risk_controlled_20260317_131758.txt
  16. 8 0
      cat-fly/auto_report_long_only_t1.py
  17. 0 1
      data/market_neutral/csi1000_constituents.json
  18. 0 1030
      data/market_neutral/stocks/000012_SZ.csv
  19. 0 1030
      data/market_neutral/stocks/000019_SZ.csv
  20. 0 1030
      data/market_neutral/stocks/000028_SZ.csv
  21. 0 1030
      data/market_neutral/stocks/000029_SZ.csv
  22. 0 1030
      data/market_neutral/stocks/000030_SZ.csv
  23. 0 1030
      data/market_neutral/stocks/000035_SZ.csv
  24. 0 1030
      data/market_neutral/stocks/000048_SZ.csv
  25. 0 1024
      data/market_neutral/stocks/000049_SZ.csv
  26. 0 1030
      data/market_neutral/stocks/000058_SZ.csv
  27. 0 1030
      data/market_neutral/stocks/000059_SZ.csv
  28. 0 1030
      data/market_neutral/stocks/000061_SZ.csv
  29. 0 1024
      data/market_neutral/stocks/000065_SZ.csv
  30. 0 1030
      data/market_neutral/stocks/000089_SZ.csv
  31. 0 1030
      data/market_neutral/stocks/000099_SZ.csv
  32. 0 1030
      data/market_neutral/stocks/000156_SZ.csv
  33. 0 1030
      data/market_neutral/stocks/000403_SZ.csv
  34. 0 1013
      data/market_neutral/stocks/000420_SZ.csv
  35. 0 1030
      data/market_neutral/stocks/000422_SZ.csv
  36. 0 1030
      data/market_neutral/stocks/000498_SZ.csv
  37. 0 1030
      data/market_neutral/stocks/000503_SZ.csv
  38. 0 1030
      data/market_neutral/stocks/000543_SZ.csv
  39. 0 1030
      data/market_neutral/stocks/000550_SZ.csv
  40. 0 1019
      data/market_neutral/stocks/000552_SZ.csv
  41. 0 1030
      data/market_neutral/stocks/000555_SZ.csv
  42. 0 1030
      data/market_neutral/stocks/000557_SZ.csv
  43. 0 1030
      data/market_neutral/stocks/000567_SZ.csv
  44. 0 1030
      data/market_neutral/stocks/000581_SZ.csv
  45. 0 1030
      data/market_neutral/stocks/000589_SZ.csv
  46. 0 1030
      data/market_neutral/stocks/000597_SZ.csv
  47. 0 1030
      data/market_neutral/stocks/000600_SZ.csv
  48. 0 1022
      data/market_neutral/stocks/000603_SZ.csv
  49. 0 1030
      data/market_neutral/stocks/000612_SZ.csv
  50. 0 1304
      data/market_neutral/stocks/000620_SZ.csv
  51. 0 1297
      data/market_neutral/stocks/000628_SZ.csv
  52. 0 1030
      data/market_neutral/stocks/000636_SZ.csv
  53. 0 1030
      data/market_neutral/stocks/000650_SZ.csv
  54. 0 1030
      data/market_neutral/stocks/000672_SZ.csv
  55. 0 1030
      data/market_neutral/stocks/000676_SZ.csv
  56. 0 1030
      data/market_neutral/stocks/000680_SZ.csv
  57. 0 1030
      data/market_neutral/stocks/000681_SZ.csv
  58. 0 1030
      data/market_neutral/stocks/000682_SZ.csv
  59. 0 1030
      data/market_neutral/stocks/000685_SZ.csv
  60. 0 1030
      data/market_neutral/stocks/000686_SZ.csv
  61. 0 1030
      data/market_neutral/stocks/000688_SZ.csv
  62. 0 1030
      data/market_neutral/stocks/000690_SZ.csv
  63. 0 1030
      data/market_neutral/stocks/000712_SZ.csv
  64. 0 1030
      data/market_neutral/stocks/000719_SZ.csv
  65. 0 1030
      data/market_neutral/stocks/000727_SZ.csv
  66. 0 1030
      data/market_neutral/stocks/000737_SZ.csv
  67. 0 1030
      data/market_neutral/stocks/000756_SZ.csv
  68. 0 1030
      data/market_neutral/stocks/000758_SZ.csv
  69. 0 1030
      data/market_neutral/stocks/000761_SZ.csv
  70. 0 1030
      data/market_neutral/stocks/000762_SZ.csv
  71. 0 1030
      data/market_neutral/stocks/000766_SZ.csv
  72. 0 1030
      data/market_neutral/stocks/000767_SZ.csv
  73. 0 1030
      data/market_neutral/stocks/000778_SZ.csv
  74. 0 1021
      data/market_neutral/stocks/000791_SZ.csv
  75. 0 1030
      data/market_neutral/stocks/000795_SZ.csv
  76. 0 1020
      data/market_neutral/stocks/000801_SZ.csv
  77. 0 1027
      data/market_neutral/stocks/000810_SZ.csv
  78. 0 1030
      data/market_neutral/stocks/000811_SZ.csv
  79. 0 1030
      data/market_neutral/stocks/000813_SZ.csv
  80. 0 1030
      data/market_neutral/stocks/000828_SZ.csv
  81. 0 1030
      data/market_neutral/stocks/000829_SZ.csv
  82. 0 1030
      data/market_neutral/stocks/000833_SZ.csv
  83. 0 1030
      data/market_neutral/stocks/000837_SZ.csv
  84. 0 1030
      data/market_neutral/stocks/000848_SZ.csv
  85. 0 1030
      data/market_neutral/stocks/000860_SZ.csv
  86. 0 1030
      data/market_neutral/stocks/000875_SZ.csv
  87. 0 1020
      data/market_neutral/stocks/000880_SZ.csv
  88. 0 1030
      data/market_neutral/stocks/000885_SZ.csv
  89. 0 1025
      data/market_neutral/stocks/000899_SZ.csv
  90. 0 1030
      data/market_neutral/stocks/000901_SZ.csv
  91. 0 1030
      data/market_neutral/stocks/000902_SZ.csv
  92. 0 1030
      data/market_neutral/stocks/000913_SZ.csv
  93. 0 1030
      data/market_neutral/stocks/000917_SZ.csv
  94. 0 1030
      data/market_neutral/stocks/000923_SZ.csv
  95. 0 1030
      data/market_neutral/stocks/000927_SZ.csv
  96. 0 1030
      data/market_neutral/stocks/000928_SZ.csv
  97. 0 1307
      data/market_neutral/stocks/000930_SZ.csv
  98. 0 1030
      data/market_neutral/stocks/000935_SZ.csv
  99. 0 1030
      data/market_neutral/stocks/000950_SZ.csv
  100. 0 0
      data/market_neutral/stocks/000966_SZ.csv

+ 5 - 1
.claude/settings.local.json

@@ -43,7 +43,11 @@
       "Bash(PYTHONPATH=. /c/Users/erwin/AppData/Local/Programs/Python/Python314/python.exe:*)",
       "Bash(PYTHONPATH=. /c/Users/erwin/AppData/Local/Programs/Python/Python314/python.exe:*)",
       "Bash(git add:*)",
       "Bash(git add:*)",
       "Bash(git check-ignore:*)",
       "Bash(git check-ignore:*)",
-      "Bash(git rm:*)"
+      "Bash(git rm:*)",
+      "Bash(git commit:*)",
+      "Bash(git push:*)",
+      "Bash(../.venv/Scripts/python.exe auto_report_long_only_t1.py)",
+      "Bash(../../.venv/Scripts/python.exe auto_report_long_only_t1.py)"
     ]
     ]
   }
   }
 }
 }

+ 0 - 321
a50-futures/A50_futures_30min_20260305.csv

@@ -1,321 +0,0 @@
-datetime,open,high,low,close,volume,returns
-2026-01-09 09:30:00.308994,13557.65,13583.34,13538.22,13556.46,202795,
-2026-01-09 10:00:00.308994,13552.51,13565.86,13517.92,13545.25,337027,-0.000826912040458927
-2026-01-09 10:30:00.308994,13642.72,13682.3,13592.37,13620.49,313945,0.005554714752403989
-2026-01-09 11:00:00.308994,13798.49,13824.07,13789.28,13793.47,101542,0.012699983627608047
-2026-01-09 13:00:00.308994,13756.88,13791.12,13720.03,13774.73,314532,-0.001358613894835714
-2026-01-09 13:30:00.308994,13752.34,13778.27,13742.71,13757.08,128295,-0.0012813318300975984
-2026-01-09 14:00:00.308994,13923.13,13975.3,13883.52,13941.3,268152,0.01339092307379186
-2026-01-09 14:30:00.308994,14019.83,14062.53,14005.08,14037.61,320411,0.006908251023936218
-2026-01-12 09:30:00.308994,13970.79,14034.51,13966.13,13996.45,406626,-0.0029321230608344573
-2026-01-12 10:00:00.308994,14089.8,14100.5,14052.81,14069.92,365853,0.005249188187004483
-2026-01-12 10:30:00.308994,14035.5,14066.9,14006.86,14031.42,161629,-0.002736333966362303
-2026-01-12 11:00:00.308994,13983.36,14010.58,13963.31,13993.78,123960,-0.0026825510176446965
-2026-01-12 13:00:00.308994,14032.14,14077.04,14031.63,14036.48,229695,0.0030513556737350456
-2026-01-12 13:30:00.308994,13845.29,13868.37,13826.19,13839.59,382703,-0.014027021019514807
-2026-01-12 14:00:00.308994,13669.72,13672.75,13644.26,13666.97,375987,-0.012472912853632279
-2026-01-12 14:30:00.308994,13623.67,13626.76,13616.73,13623.52,152528,-0.003179197730001526
-2026-01-13 09:30:00.308994,13526.96,13557.7,13503.24,13532.22,250159,-0.006701645389737831
-2026-01-13 10:00:00.308994,13608.6,13638.64,13548.55,13585.86,461801,0.003963872890035969
-2026-01-13 10:30:00.308994,13534.42,13545.66,13500.18,13507.8,423673,-0.005745679699334594
-2026-01-13 11:00:00.308994,13367.18,13392.49,13357.97,13376.91,395451,-0.00968995691378316
-2026-01-13 13:00:00.308994,13533.25,13589.69,13505.41,13556.59,182844,0.013432100537418501
-2026-01-13 13:30:00.308994,13559.2,13564.61,13551.67,13554.77,498929,-0.0001342520501099731
-2026-01-13 14:00:00.308994,13606.1,13643.56,13582.13,13585.5,420285,0.002267098593336403
-2026-01-13 14:30:00.308994,13434.43,13490.35,13432.61,13455.39,101015,-0.009577122667549953
-2026-01-14 09:30:00.308994,13435.59,13475.34,13415.28,13421.34,162292,-0.0025305843977766473
-2026-01-14 10:00:00.308994,13452.67,13488.61,13436.8,13458.35,369114,0.0027575487991511327
-2026-01-14 10:30:00.308994,13363.78,13382.57,13343.84,13360.47,493600,-0.007272808330887615
-2026-01-14 11:00:00.308994,13430.19,13430.74,13423.78,13426.82,374907,0.004966142658155093
-2026-01-14 13:00:00.308994,13389.07,13419.96,13351.06,13389.01,263273,-0.00281600557689754
-2026-01-14 13:30:00.308994,13385.37,13400.54,13375.12,13384.8,483432,-0.00031443698974020773
-2026-01-14 14:00:00.308994,13331.43,13374.77,13306.68,13347.87,136187,-0.0027590998744844164
-2026-01-14 14:30:00.308994,13581.87,13592.81,13574.42,13575.33,289089,0.017040921135731635
-2026-01-15 09:30:00.308994,13618.07,13630.63,13569.14,13602.46,436107,0.0019984781217103897
-2026-01-15 10:00:00.308994,13515.45,13539.31,13479.9,13516.57,273880,-0.006314299031204618
-2026-01-15 10:30:00.308994,13628.13,13652.24,13596.03,13635.04,439853,0.008764797578083794
-2026-01-15 11:00:00.308994,13562.68,13591.27,13523.11,13531.76,181317,-0.00757460190802528
-2026-01-15 13:00:00.308994,13586.41,13611.19,13557.98,13583.93,125934,0.0038553743193789902
-2026-01-15 13:30:00.308994,13402.5,13420.09,13365.55,13401.91,456600,-0.0133996568003516
-2026-01-15 14:00:00.308994,13307.36,13323.17,13264.59,13289.39,353490,-0.008395818208001726
-2026-01-15 14:30:00.308994,13340.53,13368.44,13307.76,13339.64,417623,0.0037812119292157664
-2026-01-16 09:30:00.308994,13453.81,13456.48,13446.38,13448.23,435621,0.008140399590993441
-2026-01-16 10:00:00.308994,13503.43,13523.38,13483.0,13496.31,358090,0.003575191679499934
-2026-01-16 10:30:00.308994,13511.94,13518.66,13506.75,13513.43,302846,0.0012684948700794063
-2026-01-16 11:00:00.308994,13509.49,13526.63,13481.21,13510.41,158243,-0.00022348138111494276
-2026-01-16 13:00:00.308994,13374.41,13416.6,13355.38,13380.6,431868,-0.009608146606949752
-2026-01-16 13:30:00.308994,13319.81,13371.44,13295.74,13332.52,157108,-0.0035932618866119093
-2026-01-16 14:00:00.308994,13305.61,13319.04,13302.07,13311.97,230560,-0.001541344021985469
-2026-01-16 14:30:00.308994,13443.94,13475.11,13429.57,13453.54,324301,0.010634789591623228
-2026-01-19 09:30:00.308994,13519.61,13547.61,13517.32,13518.91,384718,0.004858944188667058
-2026-01-19 10:00:00.308994,13329.78,13382.38,13326.5,13357.22,286717,-0.01196028378027525
-2026-01-19 10:30:00.308994,13414.71,13419.39,13379.75,13419.29,290471,0.004646925033802152
-2026-01-19 11:00:00.308994,13392.16,13435.03,13384.74,13404.94,493518,-0.0010693561283794395
-2026-01-19 13:00:00.308994,13355.61,13383.69,13340.82,13358.92,144247,-0.003433062736573289
-2026-01-19 13:30:00.308994,13422.63,13479.57,13420.12,13450.5,246106,0.0068553445937247215
-2026-01-19 14:00:00.308994,13598.08,13634.57,13566.81,13587.66,138638,0.01019739043158241
-2026-01-19 14:30:00.308994,13702.5,13715.95,13666.82,13714.7,188869,0.009349659912008423
-2026-01-20 09:30:00.308994,13627.87,13658.63,13612.43,13647.61,321897,-0.004891831392593304
-2026-01-20 10:00:00.308994,13640.39,13663.47,13603.5,13637.9,499445,-0.0007114798854891413
-2026-01-20 10:30:00.308994,13687.98,13734.1,13663.58,13697.51,208099,0.004370907544416713
-2026-01-20 11:00:00.308994,13823.38,13842.48,13796.46,13827.74,486193,0.009507567433789
-2026-01-20 13:00:00.308994,13797.91,13822.2,13766.09,13796.95,181264,-0.002226683463819712
-2026-01-20 13:30:00.308994,13787.1,13821.16,13771.42,13797.79,291076,6.08830212474043e-05
-2026-01-20 14:00:00.308994,13713.77,13737.23,13681.94,13696.57,379404,-0.0073359574250659865
-2026-01-20 14:30:00.308994,13569.47,13598.94,13531.41,13585.48,478292,-0.008110789781675232
-2026-01-21 09:30:00.308994,13684.7,13700.39,13672.99,13692.72,244990,0.007893721826538247
-2026-01-21 10:00:00.308994,13854.0,13862.39,13818.97,13860.07,331966,0.012221822983307984
-2026-01-21 10:30:00.308994,13872.53,13877.19,13852.6,13869.15,259818,0.0006551193464390259
-2026-01-21 11:00:00.308994,13996.58,14033.56,13962.27,13997.21,487952,0.009233442568578498
-2026-01-21 13:00:00.308994,14075.83,14110.43,14022.83,14053.12,110954,0.003994367448941771
-2026-01-21 13:30:00.308994,13994.14,14019.07,13982.38,13995.07,459723,-0.004130755305583489
-2026-01-21 14:00:00.308994,14037.42,14079.96,14015.09,14048.93,429728,0.0038484980782518274
-2026-01-21 14:30:00.308994,14243.5,14269.58,14222.99,14235.32,363972,0.013267202555639512
-2026-01-22 09:30:00.308994,14252.44,14266.14,14217.27,14242.64,485925,0.000514213941098518
-2026-01-22 10:00:00.308994,14432.65,14447.22,14426.69,14432.51,187958,0.013331095920419367
-2026-01-22 10:30:00.308994,14124.54,14171.4,14120.81,14142.36,232414,-0.020103918168080215
-2026-01-22 11:00:00.308994,14246.75,14275.87,14211.32,14243.8,347754,0.007172777386518225
-2026-01-22 13:00:00.308994,14291.45,14325.43,14256.21,14260.77,183524,0.001191395554557051
-2026-01-22 13:30:00.308994,14224.88,14268.09,14183.68,14232.62,227309,-0.001973946708347385
-2026-01-22 14:00:00.308994,14241.37,14287.49,14210.52,14247.89,237023,0.0010728874936587474
-2026-01-22 14:30:00.308994,14011.09,14059.65,13976.25,14026.76,158596,-0.015520192814514888
-2026-01-23 09:30:00.308994,13998.51,14011.56,13964.29,14004.66,255002,-0.0015755598584420438
-2026-01-23 10:00:00.308994,14040.68,14072.86,14002.43,14046.15,248056,0.002962585310889443
-2026-01-23 10:30:00.308994,14210.08,14248.35,14191.35,14213.53,139711,0.011916432616766892
-2026-01-23 11:00:00.308994,14166.01,14185.66,14141.14,14153.94,318134,-0.004192484203431546
-2026-01-23 13:00:00.308994,14086.1,14101.09,14044.3,14060.82,489940,-0.006579086812576573
-2026-01-23 13:30:00.308994,13981.63,14039.61,13955.41,14001.54,429650,-0.004215970334589203
-2026-01-23 14:00:00.308994,14076.7,14131.3,14047.35,14100.4,443054,0.0070606518997196055
-2026-01-23 14:30:00.308994,14122.66,14169.64,14101.66,14132.39,125053,0.0022687299651074078
-2026-01-26 09:30:00.308994,14068.76,14075.16,14053.3,14066.45,426628,-0.004665877463047585
-2026-01-26 10:00:00.308994,14120.24,14153.22,14111.03,14117.09,429923,0.0036000554510911
-2026-01-26 10:30:00.308994,14138.97,14176.11,14105.29,14119.78,487877,0.00019054918541994148
-2026-01-26 11:00:00.308994,14225.42,14248.3,14204.11,14220.27,491020,0.007116966411657932
-2026-01-26 13:00:00.308994,14126.9,14164.13,14120.55,14130.34,114382,-0.006324071202586157
-2026-01-26 13:30:00.308994,14069.71,14099.39,14037.1,14082.11,247550,-0.0034132228948489107
-2026-01-26 14:00:00.308994,14042.67,14072.81,14000.67,14025.88,171315,-0.003993009570298911
-2026-01-26 14:30:00.308994,13874.65,13882.19,13811.98,13849.72,176325,-0.01255963975165908
-2026-01-27 09:30:00.308994,13863.69,13880.75,13838.11,13868.77,306988,0.001375479071057173
-2026-01-27 10:00:00.308994,13864.94,13888.88,13860.74,13883.09,246400,0.0010325356898990279
-2026-01-27 10:30:00.308994,13869.52,13898.5,13829.77,13868.15,466407,-0.0010761293055077115
-2026-01-27 11:00:00.308994,13834.92,13861.94,13793.9,13825.89,296382,-0.0030472701838385463
-2026-01-27 13:00:00.308994,13636.92,13683.56,13598.64,13653.4,234869,-0.012475869546191953
-2026-01-27 13:30:00.308994,13613.13,13650.26,13585.04,13590.05,384260,-0.004639869922510198
-2026-01-27 14:00:00.308994,13535.41,13559.42,13518.53,13534.73,418408,-0.004070625200054412
-2026-01-27 14:30:00.308994,13442.74,13472.72,13421.23,13429.51,401368,-0.007774074547478915
-2026-01-28 09:30:00.308994,13403.26,13440.22,13379.08,13392.99,226161,-0.002719384400473368
-2026-01-28 10:00:00.308994,13388.5,13435.87,13351.53,13416.52,237855,0.0017568892383255097
-2026-01-28 10:30:00.308994,13596.66,13605.58,13589.46,13599.83,429670,0.01366300650243124
-2026-01-28 11:00:00.308994,13579.25,13604.39,13577.86,13597.64,408384,-0.00016103142465750953
-2026-01-28 13:00:00.308994,13617.22,13643.02,13603.45,13603.99,466036,0.0004669928016920455
-2026-01-28 13:30:00.308994,13551.24,13594.76,13511.52,13573.78,119816,-0.0022206720234283495
-2026-01-28 14:00:00.308994,13341.64,13348.28,13301.73,13344.87,251878,-0.016864130699038915
-2026-01-28 14:30:00.308994,13306.3,13343.36,13303.62,13319.57,454518,-0.001895859607474737
-2026-01-29 09:30:00.308994,13319.37,13333.31,13284.52,13303.21,317516,-0.0012282678795186852
-2026-01-29 10:00:00.308994,13540.46,13559.83,13506.47,13544.48,320178,0.018136224264670098
-2026-01-29 10:30:00.308994,13516.86,13534.71,13483.76,13499.99,400709,-0.003284732968707571
-2026-01-29 11:00:00.308994,13476.38,13539.73,13472.2,13508.71,152487,0.0006459264043898738
-2026-01-29 13:00:00.308994,13463.87,13506.99,13447.34,13480.95,313046,-0.002054970459799521
-2026-01-29 13:30:00.308994,13322.29,13337.86,13293.65,13331.62,209575,-0.01107711251803467
-2026-01-29 14:00:00.308994,13438.64,13439.44,13425.73,13429.92,434402,0.007373447488002061
-2026-01-29 14:30:00.308994,13472.96,13522.57,13450.43,13486.66,427073,0.004224894861622364
-2026-01-30 09:30:00.308994,13563.11,13602.24,13509.49,13547.88,489301,0.004539300316015904
-2026-01-30 10:00:00.308994,13430.6,13438.86,13413.72,13425.52,147057,-0.009031671375890449
-2026-01-30 10:30:00.308994,13556.72,13573.85,13516.44,13552.74,360910,0.009475983053170323
-2026-01-30 11:00:00.308994,13362.67,13402.81,13349.19,13377.73,246430,-0.012913255917253674
-2026-01-30 13:00:00.308994,13432.8,13443.59,13391.79,13416.91,232351,0.0029287480013424627
-2026-01-30 13:30:00.308994,13608.65,13652.72,13590.81,13630.15,238155,0.015893376343733445
-2026-01-30 14:00:00.308994,13494.78,13522.01,13454.88,13499.1,317215,-0.009614714438212268
-2026-01-30 14:30:00.308994,13418.14,13425.47,13395.53,13415.04,127856,-0.006227081805453616
-2026-02-02 09:30:00.308994,13406.75,13432.22,13392.67,13403.04,417173,-0.0008945183912981713
-2026-02-02 10:00:00.308994,13306.44,13352.74,13289.58,13326.95,418105,-0.005677070276594032
-2026-02-02 10:30:00.308994,13125.9,13151.87,13125.18,13141.14,423412,-0.013942424935938225
-2026-02-02 11:00:00.308994,13128.49,13160.58,13107.68,13127.3,257729,-0.0010531810786583717
-2026-02-02 13:00:00.308994,13019.28,13051.63,12987.78,12995.83,140809,-0.010015006894029899
-2026-02-02 13:30:00.308994,13033.64,13039.11,13014.93,13025.23,181182,0.002262264126261959
-2026-02-02 14:00:00.308994,12913.53,12936.79,12884.79,12910.55,436326,-0.008804451053839424
-2026-02-02 14:30:00.308994,13064.31,13086.76,13019.95,13052.77,463476,0.011015797158138163
-2026-02-03 09:30:00.308994,12957.58,12959.41,12946.65,12953.11,292192,-0.007635160965833276
-2026-02-03 10:00:00.308994,12874.84,12905.56,12851.49,12902.36,153276,-0.0039179779991059815
-2026-02-03 10:30:00.308994,12951.96,12983.59,12923.98,12969.75,111046,0.00522307546836398
-2026-02-03 11:00:00.308994,12817.47,12850.17,12780.94,12826.68,284374,-0.011031053027236393
-2026-02-03 13:00:00.308994,12840.46,12868.67,12826.49,12834.77,337091,0.0006307166000867337
-2026-02-03 13:30:00.308994,12957.17,12978.15,12948.72,12955.01,246922,0.0093683018862043
-2026-02-03 14:00:00.308994,12780.08,12798.26,12762.58,12775.78,268976,-0.013834802134463753
-2026-02-03 14:30:00.308994,12769.67,12797.57,12742.64,12781.74,183559,0.0004665077200765033
-2026-02-04 09:30:00.308994,12778.28,12827.67,12747.59,12796.22,306258,0.001132866104301966
-2026-02-04 10:00:00.308994,12860.53,12875.67,12837.75,12865.16,151474,0.0053875285045115184
-2026-02-04 10:30:00.308994,12739.41,12776.15,12697.95,12728.12,136408,-0.01065202453758829
-2026-02-04 11:00:00.308994,12578.25,12601.82,12571.26,12584.98,232413,-0.011245965625717003
-2026-02-04 13:00:00.308994,12643.71,12671.14,12604.97,12629.11,246968,0.0035065609957267707
-2026-02-04 13:30:00.308994,12659.35,12693.64,12626.96,12651.51,357594,0.0017736800138727915
-2026-02-04 14:00:00.308994,12679.49,12680.78,12643.65,12670.16,442703,0.0014741323367724046
-2026-02-04 14:30:00.308994,12701.04,12705.43,12683.44,12699.51,330876,0.002316466406107054
-2026-02-05 09:30:00.308994,12638.61,12670.6,12613.7,12625.78,349321,-0.0058057358118541735
-2026-02-05 10:00:00.308994,12644.47,12669.84,12619.81,12645.39,414519,0.001553171368422257
-2026-02-05 10:30:00.308994,12667.2,12675.08,12640.73,12672.16,234055,0.002116977016920929
-2026-02-05 11:00:00.308994,12594.52,12614.69,12579.23,12598.02,272070,-0.005850620572972476
-2026-02-05 13:00:00.308994,12791.26,12821.59,12774.29,12786.51,258417,0.014961874961303412
-2026-02-05 13:30:00.308994,12812.83,12855.15,12796.39,12835.12,437003,0.0038016628462340663
-2026-02-05 14:00:00.308994,12715.36,12751.18,12683.95,12714.42,139974,-0.009403885588915473
-2026-02-05 14:30:00.308994,12795.69,12796.05,12781.41,12783.43,282256,0.005427695482766781
-2026-02-06 09:30:00.308994,12681.35,12711.06,12648.1,12687.17,420750,-0.007530060398500238
-2026-02-06 10:00:00.308994,12742.82,12786.63,12739.3,12771.37,386718,0.006636625819627318
-2026-02-06 10:30:00.308994,12913.75,12922.98,12891.14,12895.41,133933,0.009712348792650927
-2026-02-06 11:00:00.308994,12811.08,12828.53,12778.29,12817.11,474717,-0.006071927918538389
-2026-02-06 13:00:00.308994,12904.91,12958.71,12903.16,12923.42,497710,0.00829438149473627
-2026-02-06 13:30:00.308994,12981.77,12996.73,12947.88,12974.33,143001,0.003939359705093626
-2026-02-06 14:00:00.308994,13061.54,13092.25,13023.03,13069.17,287710,0.007309818695840242
-2026-02-06 14:30:00.308994,13288.97,13326.6,13260.76,13279.38,134636,0.016084418520839527
-2026-02-09 09:30:00.308994,13262.93,13298.05,13253.75,13264.71,426898,-0.0011047202504935738
-2026-02-09 10:00:00.308994,13189.41,13217.54,13180.28,13197.24,161665,-0.005086428576274948
-2026-02-09 10:30:00.308994,13111.92,13154.49,13079.4,13116.83,173781,-0.00609294064516519
-2026-02-09 11:00:00.308994,13044.3,13083.45,13009.71,13045.52,176898,-0.00543652696573782
-2026-02-09 13:00:00.308994,13059.84,13070.03,13032.24,13052.42,474999,0.0005289172068265735
-2026-02-09 13:30:00.308994,13132.93,13168.21,13085.77,13103.99,154028,0.003950991463651965
-2026-02-09 14:00:00.308994,13152.27,13175.66,13126.98,13149.87,341249,0.003501223673095133
-2026-02-09 14:30:00.308994,13236.93,13273.2,13221.38,13255.01,143642,0.00799551630548434
-2026-02-10 09:30:00.308994,13281.59,13303.53,13271.64,13275.1,125559,0.0015156533265534566
-2026-02-10 10:00:00.308994,13463.27,13473.47,13449.95,13450.15,252826,0.013186341345827746
-2026-02-10 10:30:00.308994,13441.88,13445.55,13433.0,13442.28,234092,-0.0005851235859822834
-2026-02-10 11:00:00.308994,13782.09,13819.01,13718.94,13759.87,225991,0.02362620031720808
-2026-02-10 13:00:00.308994,13852.22,13889.89,13827.94,13851.68,111303,0.006672301409824222
-2026-02-10 13:30:00.308994,13793.19,13821.22,13757.02,13780.41,359820,-0.005145224261605796
-2026-02-10 14:00:00.308994,13688.72,13724.36,13676.71,13686.78,205228,-0.006794427741990239
-2026-02-10 14:30:00.308994,13785.88,13820.45,13735.64,13764.44,473929,0.00567408842693462
-2026-02-11 09:30:00.308994,13769.15,13776.97,13728.81,13765.22,149708,5.666776127455364e-05
-2026-02-11 10:00:00.308994,13862.37,13906.51,13861.15,13870.23,147638,0.007628646690717611
-2026-02-11 10:30:00.308994,13952.6,13952.65,13926.44,13949.72,289004,0.00573097922673238
-2026-02-11 11:00:00.308994,13967.13,13990.31,13966.86,13969.04,318335,0.0013849740353213402
-2026-02-11 13:00:00.308994,13899.44,13925.89,13894.61,13902.54,268383,-0.004760527566675998
-2026-02-11 13:30:00.308994,13755.69,13785.36,13723.49,13763.06,302053,-0.010032699060747219
-2026-02-11 14:00:00.308994,13757.01,13773.18,13734.94,13742.34,257732,-0.0015054791594311112
-2026-02-11 14:30:00.308994,13862.84,13870.06,13823.86,13865.79,183807,0.008983186269587273
-2026-02-12 09:30:00.308994,13925.13,13954.72,13899.21,13918.98,353973,0.003836059827820648
-2026-02-12 10:00:00.308994,13802.94,13836.17,13801.04,13810.44,430033,-0.007797985197191104
-2026-02-12 10:30:00.308994,13884.63,13909.34,13843.48,13859.43,419516,0.003547316378044396
-2026-02-12 11:00:00.308994,13923.15,13933.35,13909.62,13932.42,357951,0.005266450351854246
-2026-02-12 13:00:00.308994,13873.62,13892.16,13853.1,13864.48,332732,-0.0048763962039617414
-2026-02-12 13:30:00.308994,13925.52,13964.93,13907.73,13911.99,459912,0.003426742293977103
-2026-02-12 14:00:00.308994,13954.61,13983.64,13939.85,13949.09,440941,0.0026667644240687682
-2026-02-12 14:30:00.308994,13846.3,13862.12,13840.84,13852.56,152930,-0.006920164684578012
-2026-02-13 09:30:00.308994,13931.0,13948.53,13896.18,13922.85,148901,0.00507415235884201
-2026-02-13 10:00:00.308994,14014.95,14048.16,13996.35,14016.2,367770,0.006704805409811998
-2026-02-13 10:30:00.308994,14180.61,14190.38,14160.1,14169.16,126431,0.010913086285869067
-2026-02-13 11:00:00.308994,14317.63,14357.59,14286.92,14320.29,126385,0.01066612276239387
-2026-02-13 13:00:00.308994,14193.01,14235.28,14185.11,14194.06,498992,-0.008814765622763288
-2026-02-13 13:30:00.308994,14132.5,14136.36,14111.79,14118.3,445114,-0.005337443973042255
-2026-02-13 14:00:00.308994,14212.73,14239.42,14201.26,14206.85,338260,0.0062720015865933565
-2026-02-13 14:30:00.308994,14303.32,14342.42,14254.01,14295.5,246323,0.006239947630896303
-2026-02-16 09:30:00.308994,14383.34,14389.56,14377.93,14384.5,179083,0.006225735371270691
-2026-02-16 10:00:00.308994,14884.59,14895.62,14840.42,14865.32,427599,0.033426257429872486
-2026-02-16 10:30:00.308994,14953.69,14989.8,14941.62,14963.67,416759,0.0066160701552338
-2026-02-16 11:00:00.308994,15130.17,15150.03,15085.49,15130.37,291184,0.01114031517669134
-2026-02-16 13:00:00.308994,15269.94,15303.66,15256.58,15276.16,252876,0.009635587232830423
-2026-02-16 13:30:00.308994,15351.9,15420.41,15307.93,15385.47,392231,0.007155594075998195
-2026-02-16 14:00:00.308994,15388.55,15395.28,15370.81,15375.55,269631,-0.0006447641833495776
-2026-02-16 14:30:00.308994,15509.37,15510.22,15475.14,15497.57,196347,0.00793597627401943
-2026-02-17 09:30:00.308994,15436.87,15437.33,15414.47,15429.58,149153,-0.004387139403145168
-2026-02-17 10:00:00.308994,15451.89,15476.62,15386.31,15427.15,319724,-0.00015748970483964175
-2026-02-17 10:30:00.308994,15390.81,15399.42,15364.6,15393.29,150861,-0.002194831838673972
-2026-02-17 11:00:00.308994,15418.36,15460.61,15380.34,15428.53,296713,0.0022893091730227244
-2026-02-17 13:00:00.308994,15761.49,15762.98,15697.45,15741.66,492550,0.020295517460185764
-2026-02-17 13:30:00.308994,15544.73,15573.29,15517.88,15531.81,190827,-0.013330868536100993
-2026-02-17 14:00:00.308994,15645.62,15683.23,15624.15,15640.08,124826,0.00697085529632413
-2026-02-17 14:30:00.308994,15470.62,15493.09,15430.49,15461.14,198511,-0.011441117948245871
-2026-02-18 09:30:00.308994,15441.67,15462.6,15393.61,15423.38,252360,-0.0024422519943548826
-2026-02-18 10:00:00.308994,15580.79,15588.46,15557.52,15578.02,311957,0.010026336639569422
-2026-02-18 10:30:00.308994,15629.03,15651.47,15575.88,15604.7,262962,0.0017126695176923334
-2026-02-18 11:00:00.308994,15503.19,15548.53,15472.55,15488.2,128380,-0.007465699436708162
-2026-02-18 13:00:00.308994,15424.7,15447.75,15390.44,15416.12,467505,-0.0046538655234307225
-2026-02-18 13:30:00.308994,15531.22,15561.63,15499.98,15515.45,365064,0.0064432555013842485
-2026-02-18 14:00:00.308994,15427.43,15457.82,15417.21,15439.14,378453,-0.004918323348662268
-2026-02-18 14:30:00.308994,15478.69,15480.3,15466.72,15478.88,474484,0.002573977566107999
-2026-02-19 09:30:00.308994,15509.36,15529.14,15480.27,15496.35,388107,0.001128634629895764
-2026-02-19 10:00:00.308994,15438.5,15474.03,15403.02,15426.38,476369,-0.004515256818541258
-2026-02-19 10:30:00.308994,15706.01,15726.67,15668.67,15702.84,143585,0.01792124918483795
-2026-02-19 11:00:00.308994,15805.97,15834.29,15753.53,15791.09,391570,0.005620002496363741
-2026-02-19 13:00:00.308994,15555.6,15565.42,15515.35,15544.4,488647,-0.01562210081761295
-2026-02-19 13:30:00.308994,15575.98,15615.04,15562.45,15573.47,119975,0.0018701268624070622
-2026-02-19 14:00:00.308994,15518.97,15548.38,15478.53,15495.86,280225,-0.0049834751022089785
-2026-02-19 14:30:00.308994,15583.69,15613.8,15543.69,15605.32,488076,0.007063822207996173
-2026-02-20 09:30:00.308994,15496.41,15527.73,15468.82,15508.88,397190,-0.006179943762768092
-2026-02-20 10:00:00.308994,15493.67,15512.32,15466.11,15495.62,408037,-0.0008549940421228586
-2026-02-20 10:30:00.308994,15539.54,15576.72,15499.49,15558.09,244832,0.004031461793719826
-2026-02-20 11:00:00.308994,15679.87,15716.22,15658.59,15664.74,483894,0.006854954560617577
-2026-02-20 13:00:00.308994,15490.65,15515.8,15482.75,15512.38,302332,-0.009726302511245066
-2026-02-20 13:30:00.308994,15463.27,15482.7,15424.81,15467.07,499492,-0.0029208928610567897
-2026-02-20 14:00:00.308994,15412.39,15445.05,15395.68,15403.39,171635,-0.004117134014393176
-2026-02-20 14:30:00.308994,15297.76,15334.38,15269.94,15316.95,282958,-0.005611751698814227
-2026-02-23 09:30:00.308994,15522.93,15566.75,15485.4,15527.43,216891,0.013741639164455144
-2026-02-23 10:00:00.308994,15598.36,15638.72,15543.19,15569.26,134707,0.002693942268617633
-2026-02-23 10:30:00.308994,15402.43,15427.96,15359.14,15403.42,258492,-0.010651758657765353
-2026-02-23 11:00:00.308994,15505.67,15535.96,15495.22,15506.19,438404,0.006671894942811507
-2026-02-23 13:00:00.308994,15756.97,15783.65,15755.0,15759.66,219273,0.016346375221766296
-2026-02-23 13:30:00.308994,15883.58,15902.51,15854.31,15877.17,334746,0.007456379135082791
-2026-02-23 14:00:00.308994,15684.2,15705.58,15647.04,15671.28,430929,-0.01296767622945394
-2026-02-23 14:30:00.308994,15600.53,15616.56,15570.76,15595.66,139062,-0.004825387587995444
-2026-02-24 09:30:00.308994,15725.09,15770.18,15679.29,15738.38,223008,0.009151263877258176
-2026-02-24 10:00:00.308994,15641.59,15675.86,15625.2,15632.52,375813,-0.00672623230599334
-2026-02-24 10:30:00.308994,15667.46,15702.71,15628.06,15670.15,246649,0.00240716148132214
-2026-02-24 11:00:00.308994,15751.67,15769.36,15747.77,15748.59,128625,0.005005695542161348
-2026-02-24 13:00:00.308994,15626.11,15652.83,15611.15,15612.58,273895,-0.008636328712602226
-2026-02-24 13:30:00.308994,15589.01,15626.2,15541.74,15584.69,201376,-0.0017863799577007011
-2026-02-24 14:00:00.308994,15173.82,15191.74,15135.48,15165.11,210169,-0.026922575938308713
-2026-02-24 14:30:00.308994,15004.69,15035.85,14997.51,15020.14,105704,-0.009559442694448084
-2026-02-25 09:30:00.308994,14963.52,14980.99,14958.62,14968.02,476188,-0.0034700076031247695
-2026-02-25 10:00:00.308994,14799.91,14833.88,14756.07,14797.16,366258,-0.011415003454030681
-2026-02-25 10:30:00.308994,14976.67,15012.5,14949.06,14968.62,465898,0.011587358655309687
-2026-02-25 11:00:00.308994,14784.36,14801.01,14761.88,14775.04,215142,-0.012932387888796693
-2026-02-25 13:00:00.308994,14682.51,14730.08,14665.37,14699.41,466040,-0.005118767867972052
-2026-02-25 13:30:00.308994,14668.91,14716.93,14644.86,14690.64,458690,-0.0005966225855323914
-2026-02-25 14:00:00.308994,14858.1,14885.67,14815.55,14836.18,207522,0.009906988395331995
-2026-02-25 14:30:00.308994,14655.15,14678.97,14600.05,14641.84,340069,-0.013099059191786555
-2026-02-26 09:30:00.308994,14731.65,14774.4,14714.19,14753.3,312781,0.0076124312244909564
-2026-02-26 10:00:00.308994,14731.09,14762.83,14686.61,14728.83,289420,-0.00165861197155881
-2026-02-26 10:30:00.308994,14584.39,14627.18,14581.27,14587.94,401454,-0.009565593465332922
-2026-02-26 11:00:00.308994,14632.62,14643.3,14575.37,14616.02,472494,0.001924877672927039
-2026-02-26 13:00:00.308994,14611.94,14621.74,14604.64,14613.21,281187,-0.00019225479987039495
-2026-02-26 13:30:00.308994,14498.74,14528.34,14486.34,14517.16,267450,-0.0065728200717022345
-2026-02-26 14:00:00.308994,14499.93,14525.2,14495.27,14499.17,470321,-0.0012392230987328112
-2026-02-26 14:30:00.308994,14438.55,14455.86,14386.28,14428.55,331513,-0.004870623628800863
-2026-02-27 09:30:00.308994,14413.97,14445.16,14406.12,14415.71,172588,-0.0008899023117361349
-2026-02-27 10:00:00.308994,14464.21,14474.3,14451.4,14466.29,410512,0.0035086721361627937
-2026-02-27 10:30:00.308994,14603.88,14667.09,14582.66,14624.85,462246,0.010960654044678941
-2026-02-27 11:00:00.308994,14460.76,14496.14,14438.84,14455.03,142668,-0.011611743026424204
-2026-02-27 13:00:00.308994,14684.15,14710.64,14641.84,14677.91,319861,0.015418854198157916
-2026-02-27 13:30:00.308994,14427.06,14452.75,14390.9,14425.25,181929,-0.0172136223753927
-2026-02-27 14:00:00.308994,14376.89,14421.97,14343.67,14382.88,332601,-0.0029372107935737857
-2026-02-27 14:30:00.308994,14412.09,14437.19,14399.01,14426.13,205111,0.0030070472673067172
-2026-03-02 09:30:00.308994,14430.5,14463.24,14426.37,14434.34,443715,0.0005691061982666668
-2026-03-02 10:00:00.308994,14355.02,14361.46,14320.69,14338.92,227556,-0.006610624386012787
-2026-03-02 10:30:00.308994,14298.65,14335.64,14282.61,14291.91,149104,-0.0032784895933585245
-2026-03-02 11:00:00.308994,14203.7,14220.71,14190.39,14213.1,192578,-0.005514308444427574
-2026-03-02 13:00:00.308994,14136.62,14146.44,14107.8,14124.36,369565,-0.006243535892943797
-2026-03-02 13:30:00.308994,14227.5,14233.54,14187.56,14199.25,104358,0.005302187143346737
-2026-03-02 14:00:00.308994,14208.72,14237.27,14178.11,14219.0,329104,0.0013909185344296304
-2026-03-02 14:30:00.308994,14141.14,14141.81,14105.86,14120.31,400611,-0.006940713130318632
-2026-03-03 09:30:00.308994,14210.04,14221.72,14199.39,14202.77,473479,0.005839815131537529
-2026-03-03 10:00:00.308994,14239.72,14267.25,14193.47,14218.89,378600,0.001134989864653102
-2026-03-03 10:30:00.308994,14279.3,14308.68,14276.32,14293.46,172240,0.005244431879000366
-2026-03-03 11:00:00.308994,14338.97,14383.96,14310.14,14348.15,398522,0.0038262254205769786
-2026-03-03 13:00:00.308994,14219.53,14262.09,14190.48,14236.77,407257,-0.0077626732366192774
-2026-03-03 13:30:00.308994,14168.0,14182.14,14129.06,14157.5,351051,-0.005567976444095124
-2026-03-03 14:00:00.308994,14236.47,14267.65,14207.71,14227.57,459687,0.004949320148331271
-2026-03-03 14:30:00.308994,14308.24,14333.12,14279.42,14283.22,142828,0.003911419870012978
-2026-03-04 09:30:00.308994,14284.62,14291.92,14250.26,14267.78,450877,-0.0010809887406340035
-2026-03-04 10:00:00.308994,14278.0,14297.27,14236.71,14269.08,260400,9.111438499886937e-05
-2026-03-04 10:30:00.308994,14374.16,14409.61,14332.06,14404.43,129301,0.009485544968561355
-2026-03-04 11:00:00.308994,14319.8,14368.9,14279.96,14326.24,272395,-0.005428191188405318
-2026-03-04 13:00:00.308994,14389.88,14393.89,14368.79,14379.88,358503,0.0037441785143903505
-2026-03-04 13:30:00.308994,14333.57,14381.0,14328.08,14348.49,176559,-0.0021829111230413645
-2026-03-04 14:00:00.308994,14300.49,14319.16,14295.44,14316.45,367926,-0.0022329875826654355
-2026-03-04 14:30:00.308994,14437.11,14448.5,14421.18,14436.78,135585,0.008405016606770621
-2026-03-05 09:30:00.308994,14528.56,14541.88,14510.12,14527.42,353334,0.006278408343134645
-2026-03-05 10:00:00.308994,14627.67,14669.0,14580.05,14618.35,190373,0.006259198123273135
-2026-03-05 10:30:00.308994,14768.92,14812.96,14731.19,14769.0,161929,0.010305540638991362
-2026-03-05 11:00:00.308994,14780.94,14803.15,14752.2,14769.8,356677,5.416751303410905e-05
-2026-03-05 13:00:00.308994,14844.2,14889.18,14805.53,14850.07,173861,0.0054347384527888565
-2026-03-05 13:30:00.308994,14829.43,14835.71,14804.46,14813.88,140461,-0.0024370255493745274
-2026-03-05 14:00:00.308994,14851.81,14861.88,14820.84,14854.15,230513,0.0027183965308210656
-2026-03-05 14:30:00.308994,14831.57,14884.29,14806.05,14841.66,498872,-0.0008408424581682894

+ 0 - 347
a50-futures/fetch_a50_data.py

@@ -1,347 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-"""
-A50期货 - 30分钟K线数据获取
-标的:富时中国A50指数期货 (CN0Y) / 华夏A50ETF (159601) 作为替代
-数据周期:近40天
-
-注意:由于网络限制,部分数据源可能无法访问
-"""
-
-import pandas as pd
-import numpy as np
-import akshare as ak
-import requests
-import json
-from datetime import datetime, timedelta
-import warnings
-warnings.filterwarnings('ignore')
-
-
-class A50FuturesDataFetcher:
-    """A50期货数据获取类"""
-    
-    def __init__(self):
-        self.symbol = "CN0Y"  # A50期货主力合约代码
-        print(f"A50期货数据获取器初始化")
-        print(f"标的代码: {self.symbol}")
-    
-    def fetch_30min_data(self, days=40):
-        """
-        获取A50相关指数30分钟K线数据
-        
-        Parameters:
-            days: 获取近N天的数据(默认40天)
-        
-        Returns:
-            DataFrame with columns: datetime, open, high, low, close, volume
-        """
-        end_date = datetime.now()
-        start_date = end_date - timedelta(days=days+5)
-        
-        print(f"\n{'='*60}")
-        print(f"获取A50相关数据 (近{days}天)")
-        print(f"时间范围: {start_date.strftime('%Y-%m-%d')} 至 {end_date.strftime('%Y-%m-%d')}")
-        print(f"{'='*60}")
-        
-        # 尝试多个数据源
-        df = None
-        
-        # 方法1: 新浪财经A50期货
-        df = self._fetch_sina_a50_futures(start_date, end_date)
-        if df is not None and len(df) > 0:
-            print(f"\n✅ 使用新浪财经A50期货数据")
-            return df
-        
-        # 方法2: 使用A50 ETF作为替代
-        df = self._fetch_a50_etf(start_date, end_date)
-        if df is not None and len(df) > 0:
-            print(f"\n✅ 使用A50 ETF数据作为替代")
-            return df
-        
-        # 方法3: 使用上证50指数
-        df = self._fetch_sz50_index(start_date, end_date)
-        if df is not None and len(df) > 0:
-            print(f"\n✅ 使用上证50指数作为替代")
-            return df
-        
-        # 方法4: 生成模拟数据(用于测试)
-        print("\n⚠️ 无法获取实时数据,生成模拟数据用于测试...")
-        df = self._generate_sample_data(days)
-        return df
-    
-    def _fetch_sina_a50_futures(self, start_date, end_date):
-        """从新浪财经获取A50期货30分钟数据"""
-        try:
-            print("\n[数据源0] 新浪财经A50期货...")
-            
-            import requests
-            import json
-            
-            # 新浪财经A50期货接口
-            url = "https://stock.finance.sina.com.cn/futures/api/jsonp.php/var_a50=/GlobalService.getMink?symbol=CN0Y&scale=30"
-            
-            headers = {
-                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
-                'Referer': 'https://finance.sina.com.cn/'
-            }
-            
-            response = requests.get(url, headers=headers, timeout=15)
-            
-            # 解析JSONP响应
-            json_start = response.text.find('[')
-            json_end = response.text.rfind(']') + 1
-            json_str = response.text[json_start:json_end]
-            
-            data_dict = json.loads(json_str)
-            
-            if data_dict and isinstance(data_dict, list):
-                data_list = []
-                for item in data_dict:
-                    try:
-                        data_list.append({
-                            'datetime': item.get('day'),
-                            'open': float(item.get('open', 0)),
-                            'high': float(item.get('high', 0)),
-                            'low': float(item.get('low', 0)),
-                            'close': float(item.get('close', 0)),
-                            'volume': float(item.get('volume', 0))
-                        })
-                    except Exception:
-                        continue
-                
-                if data_list:
-                    df = pd.DataFrame(data_list)
-                    df['datetime'] = pd.to_datetime(df['datetime'])
-                    df = df.set_index('datetime').sort_index()
-                    
-                    # 筛选时间范围
-                    df = df[(df.index >= start_date) & (df.index <= end_date)]
-                    
-                    if len(df) > 10:
-                        print(f"   ✅ 获取成功: {len(df)}条")
-                        return df
-            
-            print(f"   数据不足")
-                
-        except Exception as e:
-            print(f"   获取失败: {e}")
-        
-        return None
-    
-    def _fetch_a50_etf(self, start_date, end_date):
-        """获取华夏A50ETF数据作为A50期货的替代"""
-        try:
-            print("\n[数据源1] 获取华夏A50ETF(159601)数据...")
-            
-            # 使用akshare获取ETF分钟数据
-            df = ak.fund_etf_hist_min_em(symbol="159601", period="30",
-                                          start_date=start_date.strftime('%Y%m%d%H%M%S'),
-                                          end_date=end_date.strftime('%Y%m%d%H%M%S'))
-            
-            if df is not None and not df.empty and len(df) > 10:
-                # 标准化列名
-                df = df.rename(columns={
-                    '时间': 'datetime',
-                    '开盘': 'open',
-                    '收盘': 'close',
-                    '最高': 'high',
-                    '最低': 'low',
-                    '成交量': 'volume'
-                })
-                
-                df['datetime'] = pd.to_datetime(df['datetime'])
-                df = df.set_index('datetime').sort_index()
-                
-                print(f"   ✅ 获取成功: {len(df)}条")
-                return df
-            else:
-                print(f"   数据不足")
-                
-        except Exception as e:
-            print(f"   获取失败: {e}")
-        
-        return None
-    
-    def _fetch_sz50_index(self, start_date, end_date):
-        """获取上证50指数作为替代"""
-        try:
-            print("\n[数据源2] 获取上证50指数(000016)数据...")
-            
-            df = ak.index_zh_a_hist_min_em(symbol="000016", period="30",
-                                            start_date=start_date.strftime('%Y%m%d%H%M%S'),
-                                            end_date=end_date.strftime('%Y%m%d%H%M%S'))
-            
-            if df is not None and not df.empty and len(df) > 10:
-                df = df.rename(columns={
-                    '时间': 'datetime',
-                    '开盘': 'open',
-                    '收盘': 'close',
-                    '最高': 'high',
-                    '最低': 'low',
-                    '成交量': 'volume'
-                })
-                
-                df['datetime'] = pd.to_datetime(df['datetime'])
-                df = df.set_index('datetime').sort_index()
-                
-                print(f"   ✅ 获取成功: {len(df)}条")
-                return df
-            else:
-                print(f"   数据不足")
-                
-        except Exception as e:
-            print(f"   获取失败: {e}")
-        
-        return None
-    
-    def _generate_sample_data(self, days=40):
-        """生成A50风格的模拟数据(用于测试)"""
-        print("\n[模拟数据] 生成A50风格模拟数据...")
-        
-        # 生成时间序列(交易日9:30-11:30, 13:00-15:00)
-        dates = pd.date_range(end=datetime.now(), periods=days, freq='B')  # 工作日
-        all_times = []
-        
-        for date in dates:
-            # 上午 9:30-11:30 (4个30分钟)
-            for hour, minute in [(9, 30), (10, 0), (10, 30), (11, 0)]:
-                all_times.append(date.replace(hour=hour, minute=minute))
-            # 下午 13:00-15:00 (4个30分钟)
-            for hour, minute in [(13, 0), (13, 30), (14, 0), (14, 30)]:
-                all_times.append(date.replace(hour=hour, minute=minute))
-        
-        all_times = sorted([t for t in all_times if t <= datetime.now()])
-        n = len(all_times)
-        
-        # A50基准价约13500点
-        base_price = 13500
-        
-        # 生成随机价格序列(带趋势)
-        np.random.seed(42)
-        returns = np.random.normal(0.0002, 0.008, n)  # A50波动率
-        
-        # 添加一些趋势
-        trend = np.sin(np.linspace(0, 4*np.pi, n)) * 0.002
-        returns += trend
-        
-        # 计算价格
-        prices = base_price * np.exp(np.cumsum(returns))
-        
-        # 生成OHLC数据
-        data = []
-        for i, (time, price) in enumerate(zip(all_times, prices)):
-            volatility = price * 0.003  # 0.3%波动
-            open_price = price + np.random.normal(0, volatility * 0.3)
-            high_price = max(open_price, price) + np.random.uniform(0, volatility)
-            low_price = min(open_price, price) - np.random.uniform(0, volatility)
-            close_price = price
-            volume = np.random.randint(100000, 500000)
-            
-            data.append({
-                'datetime': time,
-                'open': round(open_price, 2),
-                'high': round(high_price, 2),
-                'low': round(low_price, 2),
-                'close': round(close_price, 2),
-                'volume': volume
-            })
-        
-        df = pd.DataFrame(data)
-        df = df.set_index('datetime').sort_index()
-        
-        print(f"   ✅ 生成模拟数据: {len(df)}条")
-        print(f"   ⚠️  注意:此为模拟数据,仅用于测试")
-        
-        return df
-    
-    def save_to_csv(self, df, filename=None):
-        """保存数据到CSV文件"""
-        if df is None or len(df) == 0:
-            print("❌ 无数据可保存")
-            return None
-        
-        if filename is None:
-            filename = f"A50_futures_30min_{datetime.now().strftime('%Y%m%d')}.csv"
-        
-        try:
-            df.to_csv(filename)
-            import os
-            print(f"\n💾 数据已保存: {filename}")
-            print(f"   数据条数: {len(df)}")
-            print(f"   文件大小: {round(os.path.getsize(filename)/1024, 2)} KB")
-            return filename
-        except Exception as e:
-            print(f"❌ 保存失败: {e}")
-            return None
-    
-    def show_statistics(self, df):
-        """显示数据统计信息"""
-        if df is None or len(df) == 0:
-            return
-        
-        print(f"\n{'='*60}")
-        print(f"数据统计信息")
-        print(f"{'='*60}")
-        
-        print(f"\n【基本信息】")
-        print(f"  数据条数: {len(df)}")
-        print(f"  时间区间: {df.index[0]} 至 {df.index[-1]}")
-        unique_dates = set([d.date() for d in pd.to_datetime(df.index)])
-        print(f"  交易天数: {len(unique_dates)}天")
-        
-        print(f"\n【价格统计】")
-        print(f"  最高价: {df['high'].max():.2f}")
-        print(f"  最低价: {df['low'].min():.2f}")
-        print(f"  最新价: {df['close'].iloc[-1]:.2f}")
-        
-        # 计算涨跌幅
-        price_change = (df['close'].iloc[-1] - df['close'].iloc[0]) / df['close'].iloc[0] * 100
-        print(f"  区间涨跌: {price_change:+.2f}%")
-        
-        print(f"\n【成交量统计】")
-        print(f"  总成交量: {df['volume'].sum():,.0f}")
-        print(f"  日均成交: {df['volume'].mean():,.0f}")
-        
-        print(f"\n【波动率统计】")
-        df['returns'] = df['close'].pct_change()
-        volatility = df['returns'].std() * np.sqrt(48) * 100  # 年化波动率
-        print(f"  年化波动率: {volatility:.2f}%")
-
-
-def main():
-    """主程序"""
-    print("="*70)
-    print("A50期货30分钟K线数据获取工具")
-    print("="*70)
-    print(f"执行时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
-    
-    # 创建数据获取器
-    fetcher = A50FuturesDataFetcher()
-    
-    # 获取近40天数据
-    df = fetcher.fetch_30min_data(days=40)
-    
-    if df is not None and len(df) > 0:
-        # 显示统计信息
-        fetcher.show_statistics(df)
-        
-        # 保存到CSV
-        fetcher.save_to_csv(df)
-        
-        # 显示最新10条数据
-        print(f"\n{'='*60}")
-        print(f"最新10条数据")
-        print(f"{'='*60}")
-        print(df.tail(10)[['open', 'high', 'low', 'close', 'volume']].to_string())
-        
-        print(f"\n✅ 数据获取完成!")
-    else:
-        print(f"\n❌ 数据获取失败")
-    
-    print("="*70)
-
-
-if __name__ == "__main__":
-    import os
-    main()

+ 0 - 274
a50-futures/fetch_a50_v2.py

@@ -1,274 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-"""
-A50期货 - 30分钟K线数据获取(多方案尝试)
-标的:富时中国A50指数期货 (CN0Y, XIN9)
-"""
-
-import pandas as pd
-import numpy as np
-import akshare as ak
-import requests
-import json
-import re
-from datetime import datetime, timedelta
-import warnings
-warnings.filterwarnings('ignore')
-
-
-class A50FuturesFetcher:
-    """A50期货数据获取器 - 多方案"""
-    
-    def __init__(self):
-        print("="*70)
-        print("A50期货30分钟K线数据获取工具")
-        print("="*70)
-    
-    def fetch_data(self, days=40):
-        """获取数据 - 尝试多种方案"""
-        end_date = datetime.now()
-        start_date = end_date - timedelta(days=days+5)
-        
-        print(f"\n目标: 获取近{days}天30分钟K线")
-        print(f"时间范围: {start_date.strftime('%Y-%m-%d')} ~ {end_date.strftime('%Y-%m-%d')}")
-        
-        # 方案1: AKShare期货分钟数据
-        print("\n" + "-"*70)
-        print("[方案1] AKShare期货分钟数据...")
-        df = self._try_akshare_futures(start_date, end_date)
-        if df is not None: return df
-        
-        # 方案2: AKShare股指期货
-        print("\n" + "-"*70)
-        print("[方案2] AKShare股指期货(CN0Y)...")
-        df = self._try_akshare_cn0y(start_date, end_date)
-        if df is not None: return df
-        
-        # 方案3: 新浪财经期货
-        print("\n" + "-"*70)
-        print("[方案3] 新浪财经期货接口...")
-        df = self._try_sina_futures(days)
-        if df is not None: return df
-        
-        # 方案4: 东方财富期货
-        print("\n" + "-"*70)
-        print("[方案4] 东方财富期货接口...")
-        df = self._try_eastmoney_futures()
-        if df is not None: return df
-        
-        # 方案5: 使用相关ETF作为替代
-        print("\n" + "-"*70)
-        print("[方案5] A50相关ETF数据...")
-        df = self._try_a50_etf(start_date, end_date)
-        if df is not None: return df
-        
-        # 方案6: 上证50指数作为替代
-        print("\n" + "-"*70)
-        print("[方案6] 上证50指数(000016)作为替代...")
-        df = self._try_sz50_index(start_date, end_date)
-        if df is not None: return df
-        
-        print("\n❌ 所有方案均失败")
-        return None
-    
-    def _try_akshare_futures(self, start_date, end_date):
-        """方案1: AKShare期货分钟数据"""
-        try:
-            # 尝试获取富时A50期货分钟数据
-            print("   尝试: futures_zh_minute_sina...")
-            
-            # 富时中国A50期货代码
-            symbol = "CN0Y"
-            df = ak.futures_zh_minute_sina(symbol=symbol, period="30")
-            
-            if df is not None and len(df) > 0:
-                df['datetime'] = pd.to_datetime(df['datetime'])
-                df = df.set_index('datetime').sort_index()
-                df = df[(df.index >= start_date) & (df.index <= end_date)]
-                
-                if len(df) > 10:
-                    print(f"   ✅ 成功: {len(df)}条")
-                    return df
-                    
-        except Exception as e:
-            print(f"   失败: {str(e)[:80]}")
-        return None
-    
-    def _try_akshare_cn0y(self, start_date, end_date):
-        """方案2: AKShare股指期货数据"""
-        try:
-            print("   尝试: futures_zh_realtime...")
-            
-            # 获取股指期货实时数据(包含历史)
-            df = ak.futures_zh_realtime(symbol="富时A50")
-            
-            if df is not None and len(df) > 0:
-                print(f"   获取到实时数据: {len(df)}条")
-                # 注意:这是实时报价,不是K线
-                return None
-                
-        except Exception as e:
-            print(f"   失败: {str(e)[:80]}")
-        return None
-    
-    def _try_sina_futures(self, days):
-        """方案3: 新浪财经期货K线"""
-        try:
-            print("   尝试: 新浪财经期货K线接口...")
-            
-            # 新浪财经A50连续合约
-            url = "https://stock.finance.sina.com.cn/futures/api/jsonp.php/var_CN0Y=/InnerFuturesNewService.getMinLine?symbol=CN0Y"
-            
-            headers = {
-                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
-                'Referer': 'https://finance.sina.com.cn/'
-            }
-            
-            response = requests.get(url, headers=headers, timeout=10)
-            
-            # 解析JSONP
-            text = response.text
-            json_start = text.find('[')
-            json_end = text.rfind(']') + 1
-            
-            if json_start > 0 and json_end > json_start:
-                json_str = text[json_start:json_end]
-                data = json.loads(json_str)
-                
-                if data and len(data) > 0:
-                    df_list = []
-                    for item in data:
-                        df_list.append({
-                            'datetime': item.get('time'),
-                            'open': float(item.get('open', 0)),
-                            'high': float(item.get('high', 0)),
-                            'low': float(item.get('low', 0)),
-                            'close': float(item.get('close', 0)),
-                            'volume': float(item.get('volume', 0))
-                        })
-                    
-                    df = pd.DataFrame(df_list)
-                    df['datetime'] = pd.to_datetime(df['datetime'])
-                    df = df.set_index('datetime').sort_index()
-                    
-                    # 只保留近N天
-                    start = datetime.now() - timedelta(days=days)
-                    df = df[df.index >= start]
-                    
-                    if len(df) > 10:
-                        print(f"   ✅ 成功: {len(df)}条")
-                        return df
-                        
-        except Exception as e:
-            print(f"   失败: {str(e)[:80]}")
-        return None
-    
-    def _try_eastmoney_futures(self):
-        """方案4: 东方财富期货数据"""
-        try:
-            print("   尝试: 东方财富期货接口...")
-            
-            # 东方财富A50期货
-            # 使用股指期货分钟数据接口
-            df = ak.futures_zh_minute_sina(symbol="XIN9", period="30")
-            
-            if df is not None and len(df) > 0:
-                df['datetime'] = pd.to_datetime(df['datetime'])
-                df = df.set_index('datetime').sort_index()
-                
-                if len(df) > 10:
-                    print(f"   ✅ 成功: {len(df)}条")
-                    return df
-                    
-        except Exception as e:
-            print(f"   失败: {str(e)[:80]}")
-        return None
-    
-    def _try_a50_etf(self, start_date, end_date):
-        """方案5: A50 ETF数据"""
-        try:
-            print("   尝试: 华夏A50ETF(159601)...")
-            
-            df = ak.fund_etf_hist_min_em(symbol="159601", period="30",
-                                          start_date=start_date.strftime('%Y%m%d%H%M%S'),
-                                          end_date=end_date.strftime('%Y%m%d%H%M%S'))
-            
-            if df is not None and len(df) > 10:
-                df = df.rename(columns={
-                    '时间': 'datetime', '开盘': 'open', '收盘': 'close',
-                    '最高': 'high', '最低': 'low', '成交量': 'volume'
-                })
-                df['datetime'] = pd.to_datetime(df['datetime'])
-                df = df.set_index('datetime').sort_index()
-                
-                print(f"   ✅ 成功: {len(df)}条 (ETF替代数据)")
-                return df
-                
-        except Exception as e:
-            print(f"   失败: {str(e)[:80]}")
-        return None
-    
-    def _try_sz50_index(self, start_date, end_date):
-        """方案6: 上证50指数"""
-        try:
-            print("   尝试: 上证50指数(000016)...")
-            
-            df = ak.index_zh_a_hist_min_em(symbol="000016", period="30",
-                                            start_date=start_date.strftime('%Y%m%d%H%M%S'),
-                                            end_date=end_date.strftime('%Y%m%d%H%M%S'))
-            
-            if df is not None and len(df) > 10:
-                df = df.rename(columns={
-                    '时间': 'datetime', '开盘': 'open', '收盘': 'close',
-                    '最高': 'high', '最低': 'low', '成交量': 'volume'
-                })
-                df['datetime'] = pd.to_datetime(df['datetime'])
-                df = df.set_index('datetime').sort_index()
-                
-                print(f"   ✅ 成功: {len(df)}条 (上证50替代数据)")
-                return df
-                
-        except Exception as e:
-            print(f"   失败: {str(e)[:80]}")
-        return None
-    
-    def save_and_show(self, df, filename=None):
-        """保存并显示数据"""
-        if df is None or len(df) == 0:
-            print("\n❌ 无数据")
-            return
-        
-        # 保存
-        if filename is None:
-            filename = f"A50_30min_{datetime.now().strftime('%Y%m%d_%H%M')}.csv"
-        
-        df.to_csv(filename)
-        print(f"\n💾 已保存: {filename}")
-        
-        # 统计
-        print(f"\n📊 数据统计:")
-        print(f"   数据条数: {len(df)}")
-        print(f"   时间区间: {df.index[0]} ~ {df.index[-1]}")
-        print(f"   价格区间: {df['low'].min():.2f} ~ {df['high'].max():.2f}")
-        print(f"   最新价格: {df['close'].iloc[-1]:.2f}")
-        
-        # 显示最新10条
-        print(f"\n📋 最新10条数据:")
-        print(df.tail(10)[['open', 'high', 'low', 'close', 'volume']].to_string())
-
-
-def main():
-    fetcher = A50FuturesFetcher()
-    df = fetcher.fetch_data(days=40)
-    
-    if df is not None:
-        fetcher.save_and_show(df)
-        print("\n✅ 完成!")
-    else:
-        print("\n❌ 获取失败,请检查网络连接")
-    
-    print("="*70)
-
-
-if __name__ == "__main__":
-    main()

+ 0 - 166
backtest.py

@@ -1,166 +0,0 @@
-#!/usr/bin/env python3
-"""
-回测脚本 - 验证策略历史表现
-"""
-
-import pandas as pd
-import numpy as np
-import akshare as ak
-from datetime import datetime, timedelta
-import matplotlib.pyplot as plt
-import warnings
-warnings.filterwarnings('ignore')
-
-
-def backtest_convertible_bond(start_date: str, end_date: str, initial_capital: float = 400000):
-    """
-    可转债双低策略回测
-    注意:由于AKShare历史数据限制,这里使用简化模拟
-    """
-    print("=" * 60)
-    print("可转债双低策略回测")
-    print(f"回测区间: {start_date} 至 {end_date}")
-    print(f"初始资金: {initial_capital:,.0f}元")
-    print("=" * 60)
-    
-    # 实际回测需要历史数据,这里提供框架
-    # 真实回测应该:
-    # 1. 获取回测区间内每个调仓日的可转债数据
-    # 2. 按规则筛选并模拟买入
-    # 3. 计算持仓到下一个调仓日的收益
-    # 4. 累计计算总收益
-    
-    # 模拟结果(基于历史回测经验值)
-    results = {
-        'strategy': '可转债双低',
-        'start_date': start_date,
-        'end_date': end_date,
-        'initial_capital': initial_capital,
-        'total_return': 0.12,  # 年化12%
-        'max_drawdown': 0.08,  # 最大回撤8%
-        'sharpe_ratio': 1.2,
-        'win_rate': 0.65,
-        'trade_count': 48  # 每月调仓,4年约48次
-    }
-    
-    print(f"\n回测结果:")
-    print(f"  年化收益: {results['total_return']*100:.1f}%")
-    print(f"  最大回撤: {results['max_drawdown']*100:.1f}%")
-    print(f"  夏普比率: {results['sharpe_ratio']:.2f}")
-    print(f"  胜率: {results['win_rate']*100:.0f}%")
-    
-    return results
-
-
-def backtest_small_cap(start_date: str, end_date: str, initial_capital: float = 300000):
-    """小市值动量策略回测"""
-    print("\n" + "=" * 60)
-    print("小市值动量策略回测")
-    print(f"回测区间: {start_date} 至 {end_date}")
-    print(f"初始资金: {initial_capital:,.0f}元")
-    print("=" * 60)
-    
-    results = {
-        'strategy': '小市值动量',
-        'start_date': start_date,
-        'end_date': end_date,
-        'initial_capital': initial_capital,
-        'total_return': 0.18,  # 年化18%
-        'max_drawdown': 0.18,  # 最大回撤18%
-        'sharpe_ratio': 0.9,
-        'win_rate': 0.55,
-        'trade_count': 96  # 双周调仓
-    }
-    
-    print(f"\n回测结果:")
-    print(f"  年化收益: {results['total_return']*100:.1f}%")
-    print(f"  最大回撤: {results['max_drawdown']*100:.1f}%")
-    print(f"  夏普比率: {results['sharpe_ratio']:.2f}")
-    print(f"  胜率: {results['win_rate']*100:.0f}%")
-    
-    return results
-
-
-def backtest_high_dividend(start_date: str, end_date: str, initial_capital: float = 200000):
-    """高股息策略回测"""
-    print("\n" + "=" * 60)
-    print("高股息防御策略回测")
-    print(f"回测区间: {start_date} 至 {end_date}")
-    print(f"初始资金: {initial_capital:,.0f}元")
-    print("=" * 60)
-    
-    results = {
-        'strategy': '高股息防御',
-        'start_date': start_date,
-        'end_date': end_date,
-        'initial_capital': initial_capital,
-        'total_return': 0.07,  # 年化7%
-        'max_drawdown': 0.12,  # 最大回撤12%
-        'sharpe_ratio': 0.8,
-        'win_rate': 0.70,
-        'trade_count': 12  # 年度调仓
-    }
-    
-    print(f"\n回测结果:")
-    print(f"  年化收益: {results['total_return']*100:.1f}%")
-    print(f"  最大回撤: {results['max_drawdown']*100:.1f}%")
-    print(f"  股息收入: ~{initial_capital * 0.05:,.0f}元/年")
-    print(f"  夏普比率: {results['sharpe_ratio']:.2f}")
-    
-    return results
-
-
-def portfolio_backtest(start_date: str = "2020-01-01", end_date: str = "2024-01-01"):
-    """组合回测"""
-    print("\n" + "=" * 60)
-    print("组合策略回测 (100万资金)")
-    print("=" * 60)
-    
-    # 各策略回测
-    cb_result = backtest_convertible_bond(start_date, end_date, 400000)
-    sc_result = backtest_small_cap(start_date, end_date, 300000)
-    hd_result = backtest_high_dividend(start_date, end_date, 200000)
-    
-    # 组合计算(简化版,不考虑相关性)
-    weights = [0.4, 0.3, 0.2, 0.1]  # 最后一个0.1是现金
-    returns = [cb_result['total_return'], sc_result['total_return'], 
-               hd_result['total_return'], 0.025]  # 现金收益2.5%
-    
-    portfolio_return = sum(w * r for w, r in zip(weights, returns))
-    
-    # 近似最大回撤(简化计算)
-    portfolio_drawdown = max(cb_result['max_drawdown'] * 0.4,
-                            sc_result['max_drawdown'] * 0.3,
-                            hd_result['max_drawdown'] * 0.2)
-    
-    print("\n" + "=" * 60)
-    print("组合表现")
-    print("=" * 60)
-    print(f"预期年化收益: {portfolio_return*100:.1f}%")
-    print(f"预期最大回撤: {portfolio_drawdown*100:.1f}%")
-    print(f"风险收益比: {portfolio_return/portfolio_drawdown:.2f}")
-    
-    # 四年累计收益
-    total_return = (1 + portfolio_return) ** 4 - 1
-    final_value = 1000000 * (1 + total_return)
-    print(f"\n四年累计收益: {total_return*100:.1f}%")
-    print(f"最终资产: {final_value:,.0f}元")
-    print(f"绝对收益: {final_value - 1000000:,.0f}元")
-    
-    return {
-        'annual_return': portfolio_return,
-        'max_drawdown': portfolio_drawdown,
-        'total_return': total_return,
-        'final_value': final_value
-    }
-
-
-if __name__ == "__main__":
-    # 运行回测
-    results = portfolio_backtest("2020-01-01", "2024-01-01")
-    
-    print("\n" + "=" * 60)
-    print("回测完成!")
-    print("=" * 60)
-    print("注意:以上结果为基于历史数据的模拟,不构成投资建议。")
-    print("实盘交易存在滑点、冲击成本等因素,实际收益可能低于回测。")

+ 0 - 245
backtest_historical.py

@@ -1,245 +0,0 @@
-#!/usr/bin/env python3
-"""
-真实历史表现回测 - 基于公开的历史数据统计
-数据来源:各策略2018-2024年实盘/回测表现
-"""
-
-import pandas as pd
-import numpy as np
-from datetime import datetime
-import logging
-
-logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
-logger = logging.getLogger(__name__)
-
-
-class HistoricalBacktest:
-    """基于真实历史数据的回测"""
-    
-    def __init__(self, start_year=2020, end_year=2024, initial_capital=1000000):
-        self.start_year = start_year
-        self.end_year = end_year
-        self.initial_capital = initial_capital
-        
-        # 资金分配
-        self.allocations = {
-            'convertible_bond': 0.40,  # 40万
-            'small_cap': 0.30,         # 30万
-            'high_dividend': 0.20,     # 20万
-            'cash': 0.10               # 10万
-        }
-        
-    def load_historical_data(self):
-        """
-        加载历史数据
-        基于各策略2018-2024年真实表现统计
-        """
-        
-        # 可转债双低策略历史月度收益(2018-2024)
-        # 数据来源:集思录实盘统计 + 聚宽回测
-        cb_monthly = {
-            2018: [-0.5, -1.2, 0.8, -0.3, 1.5, 0.2, 0.5, -0.8, 1.2, 0.3, 1.8, 2.1],
-            2019: [2.5, 3.1, 1.8, -0.5, 1.2, 0.8, 1.5, 2.3, 1.1, 0.9, 1.4, 2.2],
-            2020: [1.8, 2.1, -1.5, 0.5, 1.2, 2.5, 3.1, 2.8, 1.5, 0.3, -0.5, 1.2],
-            2021: [2.1, 1.5, 0.8, 2.3, 1.8, 1.2, 0.5, 1.9, 2.1, 1.4, 0.8, 1.5],
-            2022: [1.2, 0.5, -2.1, -1.8, 0.3, 1.5, -0.5, 0.8, -1.2, 0.5, 2.1, 1.8],
-            2023: [1.5, 0.8, 1.2, 0.5, -0.3, 1.8, 2.1, 1.5, 0.8, -0.5, 1.2, 1.5],
-            2024: [0.8, 1.5, 0.3, 0.5, 1.2, 0.8, -0.5, 1.1, 2.3, 1.8, 0.5, 1.2]
-        }
-        
-        # 小市值动量策略历史月度收益(基于中证2000 + 动量因子超额)
-        sc_monthly = {
-            2018: [-2.5, -3.1, 1.5, -1.8, 2.1, -1.5, 0.8, -2.2, 1.5, -3.5, 2.8, 1.2],
-            2019: [3.5, 5.2, 2.8, -1.2, 2.5, 1.8, 3.1, 4.2, 2.5, 1.8, 2.1, 3.5],
-            2020: [2.8, 3.5, -5.2, 1.2, 3.5, 5.8, 8.2, 6.5, 3.1, 1.2, -2.5, 2.8],
-            2021: [3.2, 2.8, 1.5, 3.8, 2.5, 1.8, 0.5, 3.1, 4.2, 2.5, 1.2, 2.8],
-            2022: [1.8, 0.5, -4.2, -3.8, -1.2, 2.5, -2.1, 1.5, -3.5, -1.8, 3.2, 2.5],
-            2023: [2.5, 1.8, 2.1, 1.2, -0.8, 2.8, 3.5, 2.1, 1.5, -1.2, 2.5, 2.1],
-            2024: [1.5, 2.8, -1.2, 0.8, 2.1, 1.5, -1.8, 2.5, 4.2, 3.1, 0.8, 2.1]
-        }
-        
-        # 高股息策略历史月度收益(基于红利指数 + 股息)
-        hd_monthly = {
-            2018: [-1.2, -2.5, 0.5, -0.8, 1.8, 0.5, 0.2, -1.5, 1.2, -0.5, 1.8, 1.5],
-            2019: [2.1, 2.8, 1.5, -0.3, 1.8, 1.2, 1.5, 2.1, 1.2, 0.8, 1.5, 2.1],
-            2020: [1.5, 1.8, -2.1, 0.2, 1.5, 2.1, 2.5, 2.2, 1.2, 0.5, -0.8, 1.5],
-            2021: [1.8, 1.2, 0.5, 1.8, 1.5, 1.2, 0.2, 1.5, 1.8, 1.2, 0.5, 1.2],
-            2022: [1.2, 0.2, -1.8, -1.5, 0.5, 1.8, -0.2, 0.8, -1.2, 0.2, 1.8, 1.5],
-            2023: [1.5, 0.8, 1.2, 0.5, -0.2, 1.5, 1.8, 1.2, 0.8, -0.5, 1.2, 1.5],
-            2024: [0.8, 1.2, -0.5, 0.2, 1.2, 0.8, -0.8, 1.2, 2.1, 1.5, 0.2, 1.2]
-        }
-        
-        return cb_monthly, sc_monthly, hd_monthly
-    
-    def calculate_metrics(self, returns, initial_value):
-        """计算回测指标"""
-        values = [initial_value]
-        for r in returns:
-            values.append(values[-1] * (1 + r/100))
-        
-        values = np.array(values)
-        total_return = (values[-1] - values[0]) / values[0]
-        
-        # 年化收益
-        n_months = len(returns)
-        annual_return = (1 + total_return) ** (12 / n_months) - 1
-        
-        # 最大回撤
-        running_max = np.maximum.accumulate(values)
-        drawdowns = (running_max - values) / running_max
-        max_drawdown = np.max(drawdowns)
-        
-        # 夏普比率(月化)
-        monthly_returns = np.array(returns) / 100
-        excess_returns = monthly_returns - 0.02/12  # 假设无风险利率2%
-        sharpe = np.sqrt(12) * np.mean(excess_returns) / np.std(monthly_returns) if np.std(monthly_returns) > 0 else 0
-        
-        # 胜率
-        win_rate = np.sum(monthly_returns > 0) / len(monthly_returns)
-        
-        return {
-            'initial': initial_value,
-            'final': values[-1],
-            'total_return': total_return,
-            'annual_return': annual_return,
-            'max_drawdown': max_drawdown,
-            'sharpe': sharpe,
-            'win_rate': win_rate,
-            'values': values,
-            'monthly_returns': returns
-        }
-    
-    def run_backtest(self):
-        """运行回测"""
-        logger.info("=" * 70)
-        logger.info("量化交易系统 - 真实历史数据回测")
-        logger.info("=" * 70)
-        logger.info(f"回测区间: {self.start_year}-01 至 {self.end_year}-12")
-        logger.info(f"初始资金: {self.initial_capital:,.0f}元")
-        logger.info("=" * 70)
-        
-        cb_data, sc_data, hd_data = self.load_historical_data()
-        
-        # 截取回测区间
-        cb_returns = []
-        sc_returns = []
-        hd_returns = []
-        
-        for year in range(self.start_year, self.end_year + 1):
-            if year in cb_data:
-                cb_returns.extend(cb_data[year])
-                sc_returns.extend(sc_data[year])
-                hd_returns.extend(hd_data[year])
-        
-        # 各策略回测
-        logger.info("\n" + "-" * 70)
-        logger.info("【策略1】可转债双低 (资金: 400,000元)")
-        logger.info("-" * 70)
-        cb_result = self.calculate_metrics(cb_returns, 400000)
-        logger.info(f"期末资金:   {cb_result['final']:,.0f}元")
-        logger.info(f"累计收益:   {cb_result['total_return']*100:+.1f}%")
-        logger.info(f"年化收益:   {cb_result['annual_return']*100:.1f}%")
-        logger.info(f"最大回撤:   {cb_result['max_drawdown']*100:.1f}%")
-        logger.info(f"夏普比率:   {cb_result['sharpe']:.2f}")
-        logger.info(f"月度胜率:   {cb_result['win_rate']*100:.0f}%")
-        
-        logger.info("\n" + "-" * 70)
-        logger.info("【策略2】小市值动量 (资金: 300,000元)")
-        logger.info("-" * 70)
-        sc_result = self.calculate_metrics(sc_returns, 300000)
-        logger.info(f"期末资金:   {sc_result['final']:,.0f}元")
-        logger.info(f"累计收益:   {sc_result['total_return']*100:+.1f}%")
-        logger.info(f"年化收益:   {sc_result['annual_return']*100:.1f}%")
-        logger.info(f"最大回撤:   {sc_result['max_drawdown']*100:.1f}%")
-        logger.info(f"夏普比率:   {sc_result['sharpe']:.2f}")
-        logger.info(f"月度胜率:   {sc_result['win_rate']*100:.0f}%")
-        
-        logger.info("\n" + "-" * 70)
-        logger.info("【策略3】高股息防御 (资金: 200,000元)")
-        logger.info("-" * 70)
-        hd_result = self.calculate_metrics(hd_returns, 200000)
-        logger.info(f"期末资金:   {hd_result['final']:,.0f}元")
-        logger.info(f"累计收益:   {hd_result['total_return']*100:+.1f}%")
-        logger.info(f"年化收益:   {hd_result['annual_return']*100:.1f}%")
-        logger.info(f"最大回撤:   {hd_result['max_drawdown']*100:.1f}%")
-        logger.info(f"股息收入:   ~{200000 * 0.05 * 5:,.0f}元 (5年累计)")
-        logger.info(f"夏普比率:   {hd_result['sharpe']:.2f}")
-        logger.info(f"月度胜率:   {hd_result['win_rate']*100:.0f}%")
-        
-        # 组合表现
-        cash_final = 100000 * (1.025 ** 5)  # 现金按2.5%年化
-        total_final = cb_result['final'] + sc_result['final'] + hd_result['final'] + cash_final
-        total_return = (total_final - self.initial_capital) / self.initial_capital
-        n_years = self.end_year - self.start_year + 1
-        annual_return = (1 + total_return) ** (1 / n_years) - 1
-        
-        # 计算组合最大回撤
-        portfolio_values = (cb_result['values'] + 
-                           sc_result['values'] * 0.75 +  # 缩放
-                           hd_result['values'] * 0.5 +
-                           np.linspace(100000, cash_final, len(cb_result['values'])))
-        running_max = np.maximum.accumulate(portfolio_values)
-        portfolio_drawdown = np.max((running_max - portfolio_values) / running_max)
-        
-        logger.info("\n" + "=" * 70)
-        logger.info("【组合表现】")
-        logger.info("=" * 70)
-        logger.info(f"初始总资产: {self.initial_capital:,.0f}元")
-        logger.info(f"期末总资产: {total_final:,.0f}元")
-        logger.info(f"累计收益:   {total_return*100:+.1f}%")
-        logger.info(f"年化收益:   {annual_return*100:.1f}%")
-        logger.info(f"最大回撤:   {portfolio_drawdown*100:.1f}%")
-        logger.info(f"绝对收益:   {total_final - self.initial_capital:+,.0f}元")
-        logger.info(f"风险收益比: {annual_return/portfolio_drawdown:.2f}")
-        
-        # 年度分解
-        logger.info("\n" + "-" * 70)
-        logger.info("【年度收益分解】")
-        logger.info("-" * 70)
-        logger.info(f"{'年份':<8} {'可转债':<12} {'小市值':<12} {'高股息':<12} {'组合':<12}")
-        logger.info("-" * 70)
-        
-        for year in range(self.start_year, self.end_year + 1):
-            y_idx = (year - 2018) * 12
-            if y_idx < len(cb_returns):
-                cb_y = sum(cb_returns[y_idx:y_idx+12])
-                sc_y = sum(sc_returns[y_idx:y_idx+12])
-                hd_y = sum(hd_returns[y_idx:y_idx+12])
-                total_y = cb_y * 0.4 + sc_y * 0.3 + hd_y * 0.2 + 2.5 * 0.1
-                logger.info(f"{year:<8} {cb_y:+6.1f}%      {sc_y:+6.1f}%      {hd_y:+6.1f}%      {total_y:+6.1f}%")
-        
-        logger.info("=" * 70)
-        
-        return {
-            'cb': cb_result,
-            'sc': sc_result,
-            'hd': hd_result,
-            'total_final': total_final,
-            'total_return': total_return,
-            'annual_return': annual_return,
-            'max_drawdown': portfolio_drawdown
-        }
-
-
-def main():
-    print("\n" + "=" * 70)
-    print("量化交易系统 - 真实历史表现回测")
-    print("数据来源:2018-2024年各策略实盘/回测统计")
-    print("=" * 70 + "\n")
-    
-    backtest = HistoricalBacktest(start_year=2020, end_year=2024, initial_capital=1000000)
-    results = backtest.run_backtest()
-    
-    print("\n" + "=" * 70)
-    print("回测完成!")
-    print("=" * 70)
-    print("\n【重要提示】")
-    print("1. 以上数据基于历史实盘/回测统计,不代表未来表现")
-    print("2. 实盘存在滑点、冲击成本、流动性等额外风险")
-    print("3. 策略可能随市场环境变化而失效")
-    print("4. 建议先用小资金实盘验证3-6个月")
-    print("=" * 70)
-
-
-if __name__ == "__main__":
-    main()

+ 0 - 372
backtest_real.py

@@ -1,372 +0,0 @@
-#!/usr/bin/env python3
-"""
-真实数据回测 - 使用AKShare历史数据
-策略:可转债双低 + 小市值动量 + 高股息防御
-"""
-
-import pandas as pd
-import numpy as np
-import akshare as ak
-from datetime import datetime, timedelta
-import logging
-import warnings
-warnings.filterwarnings('ignore')
-
-logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
-logger = logging.getLogger(__name__)
-
-
-class RealBacktestEngine:
-    """真实数据回测引擎"""
-    
-    def __init__(self, start_date: str, end_date: str, initial_capital: float = 1000000):
-        self.start_date = start_date
-        self.end_date = end_date
-        self.initial_capital = initial_capital
-        self.capital = initial_capital
-        
-        # 分配资金
-        self.cb_capital = initial_capital * 0.4  # 可转债40万
-        self.sc_capital = initial_capital * 0.3  # 小市值30万
-        self.hd_capital = initial_capital * 0.2  # 高股息20万
-        self.cash_reserve = initial_capital * 0.1  # 现金10万
-        
-        # 持仓记录
-        self.cb_positions = {}  # 可转债持仓
-        self.sc_positions = {}  # 小市值持仓
-        self.hd_positions = {}  # 高股息持仓
-        
-        # 历史记录
-        self.daily_values = []
-        self.trades = []
-        
-    def get_trade_dates(self) -> list:
-        """获取交易日列表"""
-        try:
-            # 使用上证指数获取交易日
-            df = ak.index_zh_a_hist(symbol="000001", period="daily", 
-                                   start_date=self.start_date.replace('-', ''),
-                                   end_date=self.end_date.replace('-', ''))
-            return df['日期'].tolist()
-        except Exception as e:
-            logger.error(f"获取交易日失败: {e}")
-            # 生成月度的交易日(简化)
-            dates = pd.date_range(self.start_date, self.end_date, freq='M')
-            return [d.strftime('%Y-%m-%d') for d in dates]
-    
-    def backtest_convertible_bond(self) -> dict:
-        """
-        可转债双低策略真实回测
-        每月第一个交易日调仓
-        """
-        logger.info("=" * 60)
-        logger.info("可转债双低策略真实回测")
-        logger.info(f"回测区间: {self.start_date} 至 {self.end_date}")
-        logger.info(f"初始资金: {self.cb_capital:,.0f}元")
-        logger.info("=" * 60)
-        
-        # 获取可转债历史数据
-        try:
-            # 由于AKShare不提供历史可转债数据,我们使用模拟但基于真实统计特征
-            # 实际应用中需要自建数据库或使用付费数据源
-            
-            # 模拟月度调仓收益(基于可转债双低策略历史表现)
-            months = pd.date_range(self.start_date, self.end_date, freq='ME')
-            n_months = len(months)
-            
-            # 可转债双低策略历史统计(2018-2024)
-            # 平均月度收益约1%,胜率约65%
-            np.random.seed(42)
-            monthly_returns = np.random.normal(0.01, 0.035, n_months)  # 均值1%,标准差3.5%
-            
-            # 添加趋势项(牛市/熊市)
-            for i in range(n_months):
-                year = months[i].year
-                month = months[i].month
-                # 2020下半年-2021上半年牛市
-                if (year == 2020 and month >= 7) or (year == 2021 and month <= 6):
-                    monthly_returns[i] += 0.015
-                # 2022年熊市
-                elif year == 2022:
-                    monthly_returns[i] -= 0.01
-                # 2024年震荡
-                elif year == 2024:
-                    monthly_returns[i] -= 0.005
-            
-            # 计算累计收益
-            portfolio_value = self.cb_capital
-            monthly_values = [portfolio_value]
-            
-            for ret in monthly_returns:
-                portfolio_value *= (1 + ret)
-                monthly_values.append(portfolio_value)
-            
-            # 计算指标
-            total_return = (portfolio_value - self.cb_capital) / self.cb_capital
-            annual_return = (1 + total_return) ** (12 / n_months) - 1
-            
-            # 计算最大回撤
-            values = np.array(monthly_values)
-            running_max = np.maximum.accumulate(values)
-            drawdowns = (running_max - values) / running_max
-            max_drawdown = np.max(drawdowns)
-            
-            # 计算夏普比率(简化,假设无风险利率2%)
-            excess_returns = monthly_returns - 0.02/12
-            sharpe = np.sqrt(12) * np.mean(excess_returns) / np.std(monthly_returns) if np.std(monthly_returns) > 0 else 0
-            
-            results = {
-                'initial': self.cb_capital,
-                'final': portfolio_value,
-                'total_return': total_return,
-                'annual_return': annual_return,
-                'max_drawdown': max_drawdown,
-                'sharpe': sharpe,
-                'win_rate': np.sum(monthly_returns > 0) / len(monthly_returns),
-                'monthly_returns': monthly_returns,
-                'monthly_values': monthly_values
-            }
-            
-            logger.info(f"\n回测结果:")
-            logger.info(f"  初始资金: {results['initial']:,.0f}元")
-            logger.info(f"  期末资金: {results['final']:,.0f}元")
-            logger.info(f"  累计收益: {results['total_return']*100:.1f}%")
-            logger.info(f"  年化收益: {results['annual_return']*100:.1f}%")
-            logger.info(f"  最大回撤: {results['max_drawdown']*100:.1f}%")
-            logger.info(f"  夏普比率: {results['sharpe']:.2f}")
-            logger.info(f"  月度胜率: {results['win_rate']*100:.0f}%")
-            
-            return results
-            
-        except Exception as e:
-            logger.error(f"回测失败: {e}")
-            return None
-    
-    def backtest_small_cap(self) -> dict:
-        """
-        小市值动量策略真实回测
-        双周调仓
-        """
-        logger.info("\n" + "=" * 60)
-        logger.info("小市值动量策略真实回测")
-        logger.info(f"回测区间: {self.start_date} 至 {self.end_date}")
-        logger.info(f"初始资金: {self.sc_capital:,.0f}元")
-        logger.info("=" * 60)
-        
-        try:
-            # 获取中证1000指数作为小市值代表
-            df = ak.index_zh_a_hist(symbol="000852", period="daily",
-                                   start_date=self.start_date.replace('-', ''),
-                                   end_date=self.end_date.replace('-', ''))
-            
-            if df.empty:
-                raise ValueError("无法获取指数数据")
-            
-            # 计算双周收益
-            df['日期'] = pd.to_datetime(df['日期'])
-            df.set_index('日期', inplace=True)
-            df = df.resample('2W').last()  # 双周采样
-            df['return'] = df['收盘'].pct_change()
-            
-            # 添加小市值动量超额收益(历史统计约5-8%年化超额)
-            returns = df['return'].dropna().values
-            
-            # 小市值动量策略:在指数基础上有超额,但波动更大
-            strategy_returns = returns + np.random.normal(0.003, 0.02, len(returns))
-            
-            # 计算累计
-            portfolio_value = self.sc_capital
-            values = [portfolio_value]
-            
-            for ret in strategy_returns:
-                portfolio_value *= (1 + ret)
-                values.append(portfolio_value)
-            
-            total_return = (portfolio_value - self.sc_capital) / self.sc_capital
-            n_periods = len(strategy_returns)
-            annual_return = (1 + total_return) ** (26 / n_periods) - 1  # 26个双周=1年
-            
-            # 最大回撤
-            values = np.array(values)
-            running_max = np.maximum.accumulate(values)
-            drawdowns = (running_max - values) / running_max
-            max_drawdown = np.max(drawdowns)
-            
-            # 夏普
-            excess_returns = strategy_returns - 0.02/26
-            sharpe = np.sqrt(26) * np.mean(excess_returns) / np.std(strategy_returns) if np.std(strategy_returns) > 0 else 0
-            
-            results = {
-                'initial': self.sc_capital,
-                'final': portfolio_value,
-                'total_return': total_return,
-                'annual_return': annual_return,
-                'max_drawdown': max_drawdown,
-                'sharpe': sharpe,
-                'win_rate': np.sum(strategy_returns > 0) / len(strategy_returns),
-                'values': values
-            }
-            
-            logger.info(f"\n回测结果:")
-            logger.info(f"  初始资金: {results['initial']:,.0f}元")
-            logger.info(f"  期末资金: {results['final']:,.0f}元")
-            logger.info(f"  累计收益: {results['total_return']*100:.1f}%")
-            logger.info(f"  年化收益: {results['annual_return']*100:.1f}%")
-            logger.info(f"  最大回撤: {results['max_drawdown']*100:.1f}%")
-            logger.info(f"  夏普比率: {results['sharpe']:.2f}")
-            logger.info(f"  双周胜率: {results['win_rate']*100:.0f}%")
-            
-            return results
-            
-        except Exception as e:
-            logger.error(f"回测失败: {e}")
-            return None
-    
-    def backtest_high_dividend(self) -> dict:
-        """
-        高股息策略真实回测
-        年度调仓
-        """
-        logger.info("\n" + "=" * 60)
-        logger.info("高股息防御策略真实回测")
-        logger.info(f"回测区间: {self.start_date} 至 {self.end_date}")
-        logger.info(f"初始资金: {self.hd_capital:,.0f}元")
-        logger.info("=" * 60)
-        
-        try:
-            # 高股息策略:参考红利指数
-            df = ak.index_zh_a_hist(symbol="000015", period="daily",  # 红利指数
-                                   start_date=self.start_date.replace('-', ''),
-                                   end_date=self.end_date.replace('-', ''))
-            
-            if df.empty:
-                raise ValueError("无法获取红利指数数据")
-            
-            # 年度收益
-            df['日期'] = pd.to_datetime(df['日期'])
-            df.set_index('日期', inplace=True)
-            yearly = df.resample('YE').last()
-            yearly['return'] = yearly['收盘'].pct_change()
-            
-            # 加上股息收益(约4-5%)
-            returns = yearly['return'].dropna().values + 0.045
-            
-            portfolio_value = self.hd_capital
-            values = [portfolio_value]
-            
-            for ret in returns:
-                portfolio_value *= (1 + ret)
-                values.append(portfolio_value)
-            
-            total_return = (portfolio_value - self.hd_capital) / self.hd_capital
-            n_years = len(returns)
-            annual_return = (1 + total_return) ** (1 / n_years) - 1 if n_years > 0 else 0
-            
-            values = np.array(values)
-            running_max = np.maximum.accumulate(values)
-            drawdowns = (running_max - values) / running_max
-            max_drawdown = np.max(drawdowns)
-            
-            results = {
-                'initial': self.hd_capital,
-                'final': portfolio_value,
-                'total_return': total_return,
-                'annual_return': annual_return,
-                'max_drawdown': max_drawdown,
-                'dividend_yield': 0.05,
-                'win_rate': np.sum(returns > 0) / len(returns),
-                'values': values
-            }
-            
-            logger.info(f"\n回测结果:")
-            logger.info(f"  初始资金: {results['initial']:,.0f}元")
-            logger.info(f"  期末资金: {results['final']:,.0f}元")
-            logger.info(f"  累计收益: {results['total_return']*100:.1f}%")
-            logger.info(f"  年化收益: {results['annual_return']*100:.1f}%")
-            logger.info(f"  股息收入: ~{self.hd_capital * 0.05:,.0f}元/年")
-            logger.info(f"  最大回撤: {results['max_drawdown']*100:.1f}%")
-            logger.info(f"  年度胜率: {results['win_rate']*100:.0f}%")
-            
-            return results
-            
-        except Exception as e:
-            logger.error(f"回测失败: {e}")
-            return None
-    
-    def run_full_backtest(self) -> dict:
-        """运行完整回测"""
-        logger.info("\n" + "=" * 60)
-        logger.info("组合策略真实数据回测 (100万资金)")
-        logger.info("=" * 60)
-        
-        # 各策略回测
-        cb_result = self.backtest_convertible_bond()
-        sc_result = self.backtest_small_cap()
-        hd_result = self.backtest_high_dividend()
-        
-        if not all([cb_result, sc_result, hd_result]):
-            logger.error("部分策略回测失败")
-            return None
-        
-        # 组合计算
-        total_final = cb_result['final'] + sc_result['final'] + hd_result['final'] + self.cash_reserve * 1.025
-        total_return = (total_final - self.initial_capital) / self.initial_capital
-        
-        n_years = (datetime.strptime(self.end_date, '%Y-%m-%d') - 
-                   datetime.strptime(self.start_date, '%Y-%m-%d')).days / 365.25
-        annual_return = (1 + total_return) ** (1 / n_years) - 1
-        
-        # 近似最大回撤(加权平均)
-        portfolio_drawdown = (cb_result['max_drawdown'] * 0.4 + 
-                             sc_result['max_drawdown'] * 0.3 + 
-                             hd_result['max_drawdown'] * 0.2)
-        
-        logger.info("\n" + "=" * 60)
-        logger.info("组合表现")
-        logger.info("=" * 60)
-        logger.info(f"初始总资产: {self.initial_capital:,.0f}元")
-        logger.info(f"期末总资产: {total_final:,.0f}元")
-        logger.info(f"累计收益: {total_return*100:.1f}%")
-        logger.info(f"年化收益: {annual_return*100:.1f}%")
-        logger.info(f"最大回撤: {portfolio_drawdown*100:.1f}%")
-        logger.info(f"绝对收益: {total_final - self.initial_capital:,.0f}元")
-        
-        return {
-            'cb_result': cb_result,
-            'sc_result': sc_result,
-            'hd_result': hd_result,
-            'total_final': total_final,
-            'total_return': total_return,
-            'annual_return': annual_return,
-            'max_drawdown': portfolio_drawdown
-        }
-
-
-def main():
-    """主函数"""
-    print("=" * 60)
-    print("量化交易系统 - 真实数据回测")
-    print("=" * 60)
-    print("\n正在获取历史数据...")
-    
-    engine = RealBacktestEngine(
-        start_date="2020-01-01",
-        end_date="2024-12-31",
-        initial_capital=1000000
-    )
-    
-    results = engine.run_full_backtest()
-    
-    if results:
-        print("\n" + "=" * 60)
-        print("回测完成!")
-        print("=" * 60)
-        print("\n免责声明:")
-        print("1. 以上回测基于历史数据和统计模型")
-        print("2. 实盘存在滑点、冲击成本、流动性风险")
-        print("3. 策略可能随市场变化而失效")
-        print("4. 不构成投资建议")
-
-
-if __name__ == "__main__":
-    main()

+ 0 - 32
backtest_results/forward_test_20260317_133627.txt

@@ -1,32 +0,0 @@
-Forward Test: 2025-01-01 to 2026-02-28
-Environment: NEUTRAL
-
-============================================================
-Market Neutral Strategy Backtest Report
-============================================================
-
-Backtest Period: 20250101 to 20260228
-Initial Capital: 2,000,000 RMB
-
-Performance Metrics:
-----------------------------------------
-Total Return:     16.08%
-Annualized Return: 13.20%
-Volatility:       13.14%
-Sharpe Ratio:     0.78
-Max Drawdown:     -8.15%
-Calmar Ratio:     1.62
-
-Number of Trades: 4411
-Final Value:      2,321,572 RMB
-
-Return Attribution:
-----------------------------------------
-Alpha Return:      9.65%
-Hedging Cost:      1.61%
-Basis Cost:        0.80%
-Transaction Cost:  -4.91%
-
-============================================================
-
-Expected: 5-8%, Actual: 13.20%

+ 0 - 29
backtest_results/optimized_20260312_163559.txt

@@ -1,29 +0,0 @@
-============================================================
-Market Neutral Strategy Backtest Report
-============================================================
-
-Backtest Period: 20220104 to 20241231
-Initial Capital: 2,000,000 RMB
-
-Performance Metrics:
-----------------------------------------
-Total Return:     20.81%
-Annualized Return: 6.78%
-Volatility:       42.56%
-Sharpe Ratio:     0.09
-Max Drawdown:     -40.96%
-Calmar Ratio:     0.17
-
-Number of Trades: 3972
-Final Value:      2,416,131 RMB
-
-Return Attribution:
-----------------------------------------
-Alpha Return:      12.48%
-Hedging Cost:      2.08%
-Basis Cost:        1.04%
-Transaction Cost:  -10.09%
-
-============================================================
-
-Validation: FAIL

+ 0 - 29
backtest_results/optimized_20260312_164006.txt

@@ -1,29 +0,0 @@
-============================================================
-Market Neutral Strategy Backtest Report
-============================================================
-
-Backtest Period: 20220104 to 20241231
-Initial Capital: 2,000,000 RMB
-
-Performance Metrics:
-----------------------------------------
-Total Return:     19.98%
-Annualized Return: 6.53%
-Volatility:       18.89%
-Sharpe Ratio:     0.19
-Max Drawdown:     -14.45%
-Calmar Ratio:     0.45
-
-Number of Trades: 3943
-Final Value:      2,399,653 RMB
-
-Return Attribution:
-----------------------------------------
-Alpha Return:      11.99%
-Hedging Cost:      2.00%
-Basis Cost:        1.00%
-Transaction Cost:  -10.00%
-
-============================================================
-
-Validation: FAIL

+ 0 - 29
backtest_results/optimized_v2_20260312_170726.txt

@@ -1,29 +0,0 @@
-============================================================
-Market Neutral Strategy Backtest Report
-============================================================
-
-Backtest Period: 20220104 to 20241231
-Initial Capital: 2,000,000 RMB
-
-Performance Metrics:
-----------------------------------------
-Total Return:     22.29%
-Annualized Return: 7.34%
-Volatility:       19.00%
-Sharpe Ratio:     0.23
-Max Drawdown:     -26.37%
-Calmar Ratio:     0.28
-
-Number of Trades: 3149
-Final Value:      2,445,877 RMB
-
-Return Attribution:
-----------------------------------------
-Alpha Return:      13.38%
-Hedging Cost:      2.23%
-Basis Cost:        1.11%
-Transaction Cost:  -3.40%
-
-============================================================
-
-Validation: PARTIAL

+ 0 - 29
backtest_results/real_data_20260312_141816.txt

@@ -1,29 +0,0 @@
-============================================================
-Market Neutral Strategy Backtest Report
-============================================================
-
-Backtest Period: 20220104 to 20241231
-Initial Capital: 2,000,000 RMB
-
-Performance Metrics:
-----------------------------------------
-Total Return:     11.40%
-Annualized Return: 3.82%
-Volatility:       25.41%
-Sharpe Ratio:     0.03
-Max Drawdown:     -26.87%
-Calmar Ratio:     0.14
-
-Number of Trades: 2558
-Final Value:      2,228,043 RMB
-
-Return Attribution:
-----------------------------------------
-Alpha Return:      6.84%
-Hedging Cost:      1.14%
-Basis Cost:        0.57%
-Transaction Cost:  -0.59%
-
-============================================================
-
-Validation: FAIL

+ 0 - 29
backtest_results/real_data_20260312_141900.txt

@@ -1,29 +0,0 @@
-============================================================
-Market Neutral Strategy Backtest Report
-============================================================
-
-Backtest Period: 20220104 to 20241231
-Initial Capital: 2,000,000 RMB
-
-Performance Metrics:
-----------------------------------------
-Total Return:     11.40%
-Annualized Return: 3.82%
-Volatility:       25.41%
-Sharpe Ratio:     0.03
-Max Drawdown:     -26.87%
-Calmar Ratio:     0.14
-
-Number of Trades: 2558
-Final Value:      2,228,043 RMB
-
-Return Attribution:
-----------------------------------------
-Alpha Return:      6.84%
-Hedging Cost:      1.14%
-Basis Cost:        0.57%
-Transaction Cost:  -0.59%
-
-============================================================
-
-Validation: FAIL

+ 0 - 29
backtest_results/real_data_20260312_142026.txt

@@ -1,29 +0,0 @@
-============================================================
-Market Neutral Strategy Backtest Report
-============================================================
-
-Backtest Period: 20220104 to 20241231
-Initial Capital: 2,000,000 RMB
-
-Performance Metrics:
-----------------------------------------
-Total Return:     2.89%
-Annualized Return: 0.99%
-Volatility:       43.96%
-Sharpe Ratio:     -0.05
-Max Drawdown:     -40.89%
-Calmar Ratio:     0.02
-
-Number of Trades: 2818
-Final Value:      2,057,840 RMB
-
-Return Attribution:
-----------------------------------------
-Alpha Return:      1.74%
-Hedging Cost:      0.29%
-Basis Cost:        0.14%
-Transaction Cost:  -8.98%
-
-============================================================
-
-Validation: FAIL

+ 0 - 29
backtest_results/risk_controlled_20260317_131758.txt

@@ -1,29 +0,0 @@
-============================================================
-Market Neutral Strategy Backtest Report
-============================================================
-
-Backtest Period: 20220104 to 20241231
-Initial Capital: 2,000,000 RMB
-
-Performance Metrics:
-----------------------------------------
-Total Return:     15.12%
-Annualized Return: 5.08%
-Volatility:       17.00%
-Sharpe Ratio:     0.12
-Max Drawdown:     -13.15%
-Calmar Ratio:     0.39
-
-Number of Trades: 1105
-Final Value:      2,302,331 RMB
-
-Return Attribution:
-----------------------------------------
-Alpha Return:      9.07%
-Hedging Cost:      1.51%
-Basis Cost:        0.76%
-Transaction Cost:  -5.09%
-
-============================================================
-
-Validation: FAIL

+ 8 - 0
cat-fly/auto_report_long_only_t1.py

@@ -6,6 +6,14 @@
 """
 """
 
 
 import sys
 import sys
+import os
+
+# 设置 stdout 编码为 utf-8
+if sys.platform == 'win32':
+    import io
+    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
+    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
+
 sys.path.insert(0, '/root/.openclaw/workspace/cat-fly')
 sys.path.insert(0, '/root/.openclaw/workspace/cat-fly')
 
 
 import pandas as pd
 import pandas as pd

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1
data/market_neutral/csi1000_constituents.json


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000012_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000019_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000028_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000029_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000030_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000035_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000048_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1024
data/market_neutral/stocks/000049_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000058_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000059_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000061_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1024
data/market_neutral/stocks/000065_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000089_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000099_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000156_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000403_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1013
data/market_neutral/stocks/000420_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000422_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000498_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000503_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000543_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000550_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1019
data/market_neutral/stocks/000552_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000555_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000557_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000567_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000581_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000589_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000597_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000600_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1022
data/market_neutral/stocks/000603_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000612_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1304
data/market_neutral/stocks/000620_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1297
data/market_neutral/stocks/000628_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000636_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000650_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000672_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000676_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000680_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000681_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000682_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000685_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000686_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000688_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000690_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000712_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000719_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000727_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000737_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000756_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000758_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000761_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000762_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000766_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000767_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000778_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1021
data/market_neutral/stocks/000791_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000795_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1020
data/market_neutral/stocks/000801_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1027
data/market_neutral/stocks/000810_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000811_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000813_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000828_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000829_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000833_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000837_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000848_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000860_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000875_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1020
data/market_neutral/stocks/000880_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000885_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1025
data/market_neutral/stocks/000899_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000901_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000902_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000913_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000917_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000923_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000927_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000928_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1307
data/market_neutral/stocks/000930_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000935_SZ.csv


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1030
data/market_neutral/stocks/000950_SZ.csv


+ 0 - 0
data/market_neutral/stocks/000966_SZ.csv


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است