cnhkmcp 2.1.1__py3-none-any.whl → 2.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. {cnhkmcp-2.1.1.dist-info → cnhkmcp-2.1.3.dist-info}/METADATA +1 -1
  2. cnhkmcp-2.1.3.dist-info/RECORD +6 -0
  3. cnhkmcp-2.1.3.dist-info/top_level.txt +1 -0
  4. cnhkmcp/__init__.py +0 -125
  5. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/README.md +0 -38
  6. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/ace.log +0 -0
  7. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/config.json +0 -6
  8. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/ace_lib.py +0 -1510
  9. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/fetch_all_datasets.py +0 -157
  10. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/fetch_all_documentation.py +0 -132
  11. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/fetch_all_operators.py +0 -99
  12. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/helpful_functions.py +0 -180
  13. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/icon.ico +0 -0
  14. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/icon.png +0 -0
  15. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/knowledge/test.txt +0 -1
  16. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/main.py +0 -576
  17. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/process_knowledge_base.py +0 -280
  18. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/rag_engine.py +0 -356
  19. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/requirements.txt +0 -7
  20. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/run.bat +0 -3
  21. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/vector_db/_manifest.json +0 -326
  22. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/vector_db/_meta.json +0 -1
  23. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/vector_db/be5d957c-b724-46e3-91d1-999e9f5f7d28/index_metadata.pickle +0 -0
  24. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/vector_db/chroma.sqlite3 +0 -0
  25. cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242//321/211/320/266/320/246/321/206/320/274/320/261/321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/231/320/243/321/205/342/225/235/320/220/321/206/320/230/320/241.py +0 -265
  26. cnhkmcp/untracked/APP/.gitignore +0 -32
  27. cnhkmcp/untracked/APP/MODULAR_STRUCTURE.md +0 -112
  28. cnhkmcp/untracked/APP/README.md +0 -309
  29. cnhkmcp/untracked/APP/Tranformer/Transformer.py +0 -4985
  30. cnhkmcp/untracked/APP/Tranformer/ace.log +0 -0
  31. cnhkmcp/untracked/APP/Tranformer/ace_lib.py +0 -1510
  32. cnhkmcp/untracked/APP/Tranformer/helpful_functions.py +0 -180
  33. cnhkmcp/untracked/APP/Tranformer/output/Alpha_candidates.json +0 -2421
  34. cnhkmcp/untracked/APP/Tranformer/output/Alpha_candidates_/321/207/320/264/342/225/221/321/204/342/225/233/320/233.json +0 -654
  35. cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_error.json +0 -1034
  36. cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_success.json +0 -444
  37. cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_/321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/320/237/320/277/321/207/320/253/342/224/244/321/206/320/236/320/265/321/210/342/225/234/342/225/234/321/205/320/225/320/265Machine_lib.json +0 -22
  38. cnhkmcp/untracked/APP/Tranformer/parsetab.py +0 -60
  39. cnhkmcp/untracked/APP/Tranformer/template_summary.txt +0 -3182
  40. cnhkmcp/untracked/APP/Tranformer/transformer_config.json +0 -7
  41. cnhkmcp/untracked/APP/Tranformer/validator.py +0 -889
  42. cnhkmcp/untracked/APP/ace.log +0 -69
  43. cnhkmcp/untracked/APP/ace_lib.py +0 -1510
  44. cnhkmcp/untracked/APP/blueprints/__init__.py +0 -6
  45. cnhkmcp/untracked/APP/blueprints/feature_engineering.py +0 -347
  46. cnhkmcp/untracked/APP/blueprints/idea_house.py +0 -221
  47. cnhkmcp/untracked/APP/blueprints/inspiration_house.py +0 -432
  48. cnhkmcp/untracked/APP/blueprints/paper_analysis.py +0 -570
  49. cnhkmcp/untracked/APP/custom_templates/templates.json +0 -1257
  50. cnhkmcp/untracked/APP/give_me_idea/BRAIN_Alpha_Template_Expert_SystemPrompt.md +0 -400
  51. cnhkmcp/untracked/APP/give_me_idea/ace_lib.py +0 -1510
  52. cnhkmcp/untracked/APP/give_me_idea/alpha_data_specific_template_master.py +0 -252
  53. cnhkmcp/untracked/APP/give_me_idea/fetch_all_datasets.py +0 -157
  54. cnhkmcp/untracked/APP/give_me_idea/fetch_all_operators.py +0 -99
  55. cnhkmcp/untracked/APP/give_me_idea/helpful_functions.py +0 -180
  56. cnhkmcp/untracked/APP/give_me_idea/what_is_Alpha_template.md +0 -11
  57. cnhkmcp/untracked/APP/helpful_functions.py +0 -180
  58. cnhkmcp/untracked/APP/hkSimulator/ace_lib.py +0 -1497
  59. cnhkmcp/untracked/APP/hkSimulator/autosimulator.py +0 -447
  60. cnhkmcp/untracked/APP/hkSimulator/helpful_functions.py +0 -180
  61. cnhkmcp/untracked/APP/mirror_config.txt +0 -20
  62. cnhkmcp/untracked/APP/operaters.csv +0 -129
  63. cnhkmcp/untracked/APP/requirements.txt +0 -53
  64. cnhkmcp/untracked/APP/run_app.bat +0 -28
  65. cnhkmcp/untracked/APP/run_app.sh +0 -34
  66. cnhkmcp/untracked/APP/setup_tsinghua.bat +0 -39
  67. cnhkmcp/untracked/APP/setup_tsinghua.sh +0 -43
  68. cnhkmcp/untracked/APP/simulator/alpha_submitter.py +0 -404
  69. cnhkmcp/untracked/APP/simulator/simulator_wqb.py +0 -618
  70. cnhkmcp/untracked/APP/ssrn-3332513.pdf +6 -109201
  71. cnhkmcp/untracked/APP/static/brain.js +0 -589
  72. cnhkmcp/untracked/APP/static/decoder.js +0 -1540
  73. cnhkmcp/untracked/APP/static/feature_engineering.js +0 -1729
  74. cnhkmcp/untracked/APP/static/idea_house.js +0 -937
  75. cnhkmcp/untracked/APP/static/inspiration.js +0 -465
  76. cnhkmcp/untracked/APP/static/inspiration_house.js +0 -868
  77. cnhkmcp/untracked/APP/static/paper_analysis.js +0 -390
  78. cnhkmcp/untracked/APP/static/script.js +0 -3082
  79. cnhkmcp/untracked/APP/static/simulator.js +0 -597
  80. cnhkmcp/untracked/APP/static/styles.css +0 -3127
  81. cnhkmcp/untracked/APP/static/usage_widget.js +0 -508
  82. cnhkmcp/untracked/APP/templates/alpha_inspector.html +0 -511
  83. cnhkmcp/untracked/APP/templates/feature_engineering.html +0 -960
  84. cnhkmcp/untracked/APP/templates/idea_house.html +0 -564
  85. cnhkmcp/untracked/APP/templates/index.html +0 -932
  86. cnhkmcp/untracked/APP/templates/inspiration_house.html +0 -861
  87. cnhkmcp/untracked/APP/templates/paper_analysis.html +0 -91
  88. cnhkmcp/untracked/APP/templates/simulator.html +0 -343
  89. cnhkmcp/untracked/APP/templates/transformer_web.html +0 -580
  90. cnhkmcp/untracked/APP/usage.md +0 -351
  91. cnhkmcp/untracked/APP//321/207/342/225/235/320/250/321/205/320/230/320/226/321/204/342/225/225/320/220/321/211/320/221/320/243/321/206/320/261/320/265/ace_lib.py +0 -1510
  92. cnhkmcp/untracked/APP//321/207/342/225/235/320/250/321/205/320/230/320/226/321/204/342/225/225/320/220/321/211/320/221/320/243/321/206/320/261/320/265/brain_alpha_inspector.py +0 -712
  93. cnhkmcp/untracked/APP//321/207/342/225/235/320/250/321/205/320/230/320/226/321/204/342/225/225/320/220/321/211/320/221/320/243/321/206/320/261/320/265/helpful_functions.py +0 -180
  94. cnhkmcp/untracked/APP//321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/231/320/243/321/205/342/225/235/320/220/321/206/320/230/320/241.py +0 -2456
  95. cnhkmcp/untracked/arXiv_API_Tool_Manual.md +0 -490
  96. cnhkmcp/untracked/arxiv_api.py +0 -229
  97. cnhkmcp/untracked/forum_functions.py +0 -998
  98. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272/forum_functions.py +0 -407
  99. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272/platform_functions.py +0 -2415
  100. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272/user_config.json +0 -31
  101. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272//321/210/320/276/320/271AI/321/210/320/277/342/225/227/321/210/342/224/220/320/251/321/204/342/225/225/320/272/321/206/320/246/320/227/321/206/320/261/320/263/321/206/320/255/320/265/321/205/320/275/320/266/321/204/342/225/235/320/252/321/204/342/225/225/320/233/321/210/342/225/234/342/225/234/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270.md +0 -101
  102. cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272//321/211/320/225/320/235/321/207/342/225/234/320/276/321/205/320/231/320/235/321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/230/320/241_/321/205/320/276/320/231/321/210/320/263/320/225/321/205/342/224/220/320/225/321/210/320/266/320/221/321/204/342/225/233/320/255/321/210/342/225/241/320/246/321/205/320/234/320/225.py +0 -190
  103. cnhkmcp/untracked/platform_functions.py +0 -2886
  104. cnhkmcp/untracked/sample_mcp_config.json +0 -11
  105. cnhkmcp/untracked/user_config.json +0 -31
  106. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/320/237/320/222/321/210/320/220/320/223/321/206/320/246/320/227/321/206/320/261/320/263_BRAIN_Alpha_Test_Requirements_and_Tips.md +0 -202
  107. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_Alpha_explaination_workflow.md +0 -56
  108. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_BRAIN_6_Tips_Datafield_Exploration_Guide.md +0 -194
  109. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_BRAIN_Alpha_Improvement_Workflow.md +0 -101
  110. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_Dataset_Exploration_Expert_Manual.md +0 -436
  111. cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_daily_report_workflow.md +0 -128
  112. cnhkmcp/untracked//321/211/320/225/320/235/321/207/342/225/234/320/276/321/205/320/231/320/235/321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/230/320/241_/321/205/320/276/320/231/321/210/320/263/320/225/321/205/342/224/220/320/225/321/210/320/266/320/221/321/204/342/225/233/320/255/321/210/342/225/241/320/246/321/205/320/234/320/225.py +0 -190
  113. cnhkmcp-2.1.1.dist-info/RECORD +0 -115
  114. cnhkmcp-2.1.1.dist-info/top_level.txt +0 -1
  115. {cnhkmcp-2.1.1.dist-info → cnhkmcp-2.1.3.dist-info}/WHEEL +0 -0
  116. {cnhkmcp-2.1.1.dist-info → cnhkmcp-2.1.3.dist-info}/entry_points.txt +0 -0
  117. {cnhkmcp-2.1.1.dist-info → cnhkmcp-2.1.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,511 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>BRAIN Alpha 跨界连锁 - 缘分一道桥</title>
7
- <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
8
- <style>
9
- .inspector-container {
10
- max-width: 1200px;
11
- margin: 0 auto;
12
- padding: 20px;
13
- }
14
- .login-section, .filter-section, .results-section {
15
- background: white;
16
- padding: 20px;
17
- border-radius: 8px;
18
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
19
- margin-bottom: 20px;
20
- }
21
- .form-group {
22
- margin-bottom: 15px;
23
- }
24
- .form-group label {
25
- display: block;
26
- margin-bottom: 5px;
27
- font-weight: bold;
28
- }
29
- .form-group input {
30
- width: 100%;
31
- padding: 8px;
32
- border: 1px solid #ddd;
33
- border-radius: 4px;
34
- }
35
- .alpha-item {
36
- border: 1px solid #eee;
37
- margin-bottom: 10px;
38
- border-radius: 4px;
39
- overflow: hidden;
40
- }
41
- .alpha-header {
42
- background: #f8f9fa;
43
- padding: 10px 15px;
44
- cursor: pointer;
45
- display: flex;
46
- justify-content: space-between;
47
- align-items: center;
48
- }
49
- .alpha-header:hover {
50
- background: #e9ecef;
51
- }
52
- .alpha-details {
53
- padding: 15px;
54
- display: none;
55
- border-top: 1px solid #eee;
56
- }
57
- .alpha-details.active {
58
- display: block;
59
- }
60
- .variant-btn {
61
- margin: 5px;
62
- padding: 8px 12px;
63
- background: #fff;
64
- border: 1px solid #007bff;
65
- color: #007bff;
66
- border-radius: 4px;
67
- cursor: pointer;
68
- transition: all 0.2s;
69
- }
70
- .variant-btn:hover {
71
- background: #007bff;
72
- color: white;
73
- }
74
- .variant-btn.simulating {
75
- background: #ffc107;
76
- border-color: #ffc107;
77
- color: #000;
78
- cursor: wait;
79
- }
80
- .variant-btn.success {
81
- background: #28a745;
82
- border-color: #28a745;
83
- color: white;
84
- }
85
- .variant-btn.sharpe-low {
86
- background: #ffc107;
87
- border-color: #ffc107;
88
- color: #000;
89
- }
90
- .variant-btn.sharpe-high {
91
- background: #6f42c1;
92
- border-color: #6f42c1;
93
- color: white;
94
- }
95
- .variant-btn.error {
96
- background: #dc3545;
97
- border-color: #dc3545;
98
- color: white;
99
- }
100
- .btn-warning {
101
- background-color: #ffc107;
102
- color: #212529;
103
- border: 1px solid #ffc107;
104
- padding: 8px 16px;
105
- border-radius: 4px;
106
- cursor: pointer;
107
- font-size: 14px;
108
- }
109
- .btn-warning:hover {
110
- background-color: #e0a800;
111
- border-color: #d39e00;
112
- }
113
- .btn-warning:disabled {
114
- background-color: #ffeeba;
115
- border-color: #ffeeba;
116
- cursor: not-allowed;
117
- opacity: 0.65;
118
- }
119
- .loading {
120
- display: none;
121
- text-align: center;
122
- padding: 20px;
123
- }
124
- .hidden {
125
- display: none;
126
- }
127
- </style>
128
- </head>
129
- <body>
130
- <div class="inspector-container">
131
- <header style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;">
132
- <h1>🌉 缘分一道桥 (Alpha 跨区连锁)</h1>
133
- <a href="/" class="btn btn-secondary">返回主页</a>
134
- </header>
135
-
136
- <div class="instructions-section" style="background: #e9ecef; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
137
- <h3 style="margin-top: 0;">📖 使用说明</h3>
138
- <ol style="padding-left: 20px; margin-bottom: 0; line-height: 1.6;">
139
- <li>获取一段时间内的Alpha列表</li>
140
- <li>分析每个Alpha里的数据字段并进行强替换,查看是否在其他Region/Universe/Delay有同样字段</li>
141
- <li>生成新的Alpha</li>
142
- <li>本页面的回测方式为排队回测,一个完成后才会发送另一个,因此中途退出页面会中断回测</li>
143
- <li>过长的回测队列有时会因为账号超时登出而出现连续失败,因此不建议选择过长时间跨度</li>
144
- <li>如想批量回测,请下载所有待回测的Alpha并选择首页回测器进行回测</li>
145
- <li>如果你想,你可以输入个很大的时间范围,下载所有表达式,慢慢进行批量回测。</li>
146
- <li>出现‘Field 'maxPercent' has no availability or not found. Intersection is empty’这类报错无需担心</li>
147
- <li>如果您一个都桥不出来,说明您使用了太多model data</li>
148
- <li>关于使用AI以跨区搭桥,我们已在72变里更新,跨区变换,最好还是使用72变功能</li>
149
- <li>对了,我们还有Alpha ID模式,您把差点可以提交的AlphaID放进来,说不定会在其他地方找到缘分</li>
150
- </ol>
151
- </div>
152
-
153
- <!-- Login Section -->
154
- <div id="loginSection" class="login-section">
155
- <h2>登录 BRAIN</h2>
156
- <div class="form-group">
157
- <label>用户名 (邮箱)</label>
158
- <input type="text" id="username" placeholder="请输入您的邮箱">
159
- </div>
160
- <div class="form-group">
161
- <label>密码</label>
162
- <input type="password" id="password" placeholder="请输入您的密码">
163
- </div>
164
- <button onclick="handleLogin()" class="btn btn-primary">登录</button>
165
- <div id="loginStatus" style="margin-top: 10px;"></div>
166
- </div>
167
-
168
- <!-- Main Content (Hidden until login) -->
169
- <div id="mainContent" class="hidden">
170
- <!-- Filter Section -->
171
- <div class="filter-section">
172
- <h2>选择模式</h2>
173
- <div style="margin-bottom: 15px;">
174
- <label><input type="radio" name="fetchMode" value="date" checked onclick="toggleMode()"> 按日期范围</label>
175
- <label style="margin-left: 20px;"><input type="radio" name="fetchMode" value="id" onclick="toggleMode()"> 指定 Alpha ID</label>
176
- </div>
177
-
178
- <div id="dateModeInputs">
179
- <h3>选择Alpha提交的日期范围(不建议超过30天)</h3>
180
- <div style="display: flex; gap: 20px;">
181
- <div class="form-group" style="flex: 1;">
182
- <label>开始日期</label>
183
- <input type="date" id="startDate">
184
- </div>
185
- <div class="form-group" style="flex: 1;">
186
- <label>结束日期</label>
187
- <input type="date" id="endDate">
188
- </div>
189
- </div>
190
- </div>
191
-
192
- <div id="idModeInputs" class="hidden">
193
- <h3>输入 Alpha ID (用逗号、空格或换行分隔)</h3>
194
- <div class="form-group">
195
- <textarea id="alphaIds" rows="5" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;" placeholder="例如: QPdZrdQG, abc12345"></textarea>
196
- </div>
197
- </div>
198
-
199
- <button onclick="fetchAlphas()" class="btn btn-primary">获取 Alpha 并分析</button>
200
- <button onclick="downloadResults()" class="btn btn-secondary" id="downloadBtn" disabled>下载所有待回测Alpha</button>
201
- <button onclick="queueAllSimulations()" class="btn btn-warning" id="queueBtn" disabled>一键全部排队回测</button>
202
- </div>
203
-
204
- <!-- Results Section -->
205
- <div class="results-section">
206
- <h2>Alpha 列表 <span id="alphaCount"></span></h2>
207
- <div id="loadingIndicator" class="loading">
208
- 正在分析 Alpha... 请耐心等待...
209
- </div>
210
- <div id="alphasList"></div>
211
- </div>
212
- </div>
213
- </div>
214
-
215
- <script>
216
- let currentSessionId = null;
217
- let analyzedAlphas = [];
218
-
219
- async function handleLogin() {
220
- const username = document.getElementById('username').value;
221
- const password = document.getElementById('password').value;
222
- const statusDiv = document.getElementById('loginStatus');
223
-
224
- statusDiv.textContent = '正在登录...';
225
-
226
- try {
227
- const response = await fetch('/api/yuanfen/login', {
228
- method: 'POST',
229
- headers: {'Content-Type': 'application/json'},
230
- body: JSON.stringify({username, password})
231
- });
232
-
233
- const data = await response.json();
234
-
235
- if (data.success) {
236
- statusDiv.textContent = '登录成功!';
237
- statusDiv.style.color = 'green';
238
- currentSessionId = data.session_id;
239
- document.getElementById('loginSection').classList.add('hidden');
240
- document.getElementById('mainContent').classList.remove('hidden');
241
- } else {
242
- statusDiv.textContent = '登录失败:' + data.message;
243
- statusDiv.style.color = 'red';
244
- }
245
- } catch (e) {
246
- statusDiv.textContent = '错误:' + e.message;
247
- statusDiv.style.color = 'red';
248
- }
249
- }
250
-
251
- function toggleMode() {
252
- const mode = document.querySelector('input[name="fetchMode"]:checked').value;
253
- if (mode === 'date') {
254
- document.getElementById('dateModeInputs').classList.remove('hidden');
255
- document.getElementById('idModeInputs').classList.add('hidden');
256
- } else {
257
- document.getElementById('dateModeInputs').classList.add('hidden');
258
- document.getElementById('idModeInputs').classList.remove('hidden');
259
- }
260
- }
261
-
262
- async function fetchAlphas() {
263
- const mode = document.querySelector('input[name="fetchMode"]:checked').value;
264
- let payload = {
265
- session_id: currentSessionId,
266
- mode: mode === 'date' ? 'date_range' : 'ids'
267
- };
268
-
269
- if (mode === 'date') {
270
- const startDate = document.getElementById('startDate').value;
271
- const endDate = document.getElementById('endDate').value;
272
- if (!startDate || !endDate) {
273
- alert('请选择开始和结束日期');
274
- return;
275
- }
276
- payload.start_date = startDate;
277
- payload.end_date = endDate;
278
- } else {
279
- const alphaIds = document.getElementById('alphaIds').value;
280
- if (!alphaIds.trim()) {
281
- alert('请输入 Alpha ID');
282
- return;
283
- }
284
- payload.alpha_ids = alphaIds;
285
- }
286
-
287
- const loadingIndicator = document.getElementById('loadingIndicator');
288
- loadingIndicator.style.display = 'block';
289
- loadingIndicator.textContent = '正在初始化请求...';
290
- document.getElementById('alphasList').innerHTML = '';
291
-
292
- try {
293
- const response = await fetch('/api/yuanfen/fetch_alphas', {
294
- method: 'POST',
295
- headers: {'Content-Type': 'application/json'},
296
- body: JSON.stringify(payload)
297
- });
298
-
299
- const reader = response.body.getReader();
300
- const decoder = new TextDecoder();
301
- let buffer = '';
302
-
303
- while (true) {
304
- const { done, value } = await reader.read();
305
- if (done) break;
306
-
307
- buffer += decoder.decode(value, { stream: true });
308
- const lines = buffer.split('\n');
309
- buffer = lines.pop(); // Keep the last incomplete line
310
-
311
- for (const line of lines) {
312
- if (!line.trim()) continue;
313
- try {
314
- const msg = JSON.parse(line);
315
- if (msg.type === 'progress') {
316
- loadingIndicator.textContent = msg.message;
317
- } else if (msg.type === 'result') {
318
- if (msg.success) {
319
- analyzedAlphas = msg.alphas;
320
- document.getElementById('alphaCount').textContent = `(${analyzedAlphas.length})`;
321
- document.getElementById('downloadBtn').disabled = false;
322
- document.getElementById('queueBtn').disabled = false;
323
- renderAlphas(analyzedAlphas);
324
- } else {
325
- throw new Error(msg.message || 'Unknown error');
326
- }
327
- } else if (msg.type === 'error') {
328
- throw new Error(msg.message);
329
- }
330
- } catch (e) {
331
- console.error("Error parsing stream:", e);
332
- }
333
- }
334
- }
335
- } catch (e) {
336
- alert('获取 Alpha 失败:' + e.message);
337
- } finally {
338
- loadingIndicator.style.display = 'none';
339
- }
340
- }
341
-
342
- function renderAlphas(alphas) {
343
- const container = document.getElementById('alphasList');
344
- container.innerHTML = '';
345
-
346
- alphas.forEach((alpha, index) => {
347
- const div = document.createElement('div');
348
- div.className = 'alpha-item';
349
-
350
- const variantsHtml = alpha.variants.map(v => {
351
- const s = v.diff_settings;
352
- const label = `${s.region}/${s.universe}/delay_${s.delay}`;
353
- // Encode payload to pass to simulate function
354
- const payloadEncoded = encodeURIComponent(JSON.stringify(v.simulation_payload));
355
- return `<button class="variant-btn" onclick="simulateVariant(this, '${payloadEncoded}')">${label}</button>`;
356
- }).join('');
357
-
358
- div.innerHTML = `
359
- <div class="alpha-header" onclick="toggleDetails(${index})">
360
- <span>${alpha.id}${alpha.dateSubmitted ? ' - ' + alpha.dateSubmitted : ''}</span>
361
- <span>${alpha.variants.length} 个可用变体</span>
362
- </div>
363
- <div class="alpha-details" id="details-${index}">
364
- <p><strong>表达式:</strong> <code>${alpha.expression}</code></p>
365
- <div class="variants-list">
366
- ${variantsHtml || '未找到有效变体。'}
367
- </div>
368
- </div>
369
- `;
370
- container.appendChild(div);
371
- });
372
- }
373
-
374
- function toggleDetails(index) {
375
- const details = document.getElementById(`details-${index}`);
376
- details.classList.toggle('active');
377
- }
378
-
379
- async function simulateVariant(btn, payloadEncoded) {
380
- // Allow retry if it was error, but prevent double click if simulating
381
- if (btn.classList.contains('simulating')) return;
382
-
383
- // Reset state for retry
384
- btn.classList.remove('error');
385
- btn.classList.remove('success');
386
- btn.classList.remove('sharpe-low');
387
- btn.classList.remove('sharpe-high');
388
- const originalText = btn.textContent; // Keep original label if needed, but we overwrite it
389
-
390
- const payload = JSON.parse(decodeURIComponent(payloadEncoded));
391
-
392
- btn.textContent = '回测中...';
393
- btn.classList.add('simulating');
394
-
395
- try {
396
- const response = await fetch('/api/yuanfen/simulate', {
397
- method: 'POST',
398
- headers: {'Content-Type': 'application/json'},
399
- body: JSON.stringify({
400
- session_id: currentSessionId,
401
- payload: payload
402
- })
403
- });
404
-
405
- const data = await response.json();
406
-
407
- if (data.success) {
408
- btn.classList.remove('simulating');
409
-
410
- const res = data.result.is;
411
- const sharpe = res.sharpe;
412
-
413
- if (sharpe > 1.5) {
414
- btn.classList.add('sharpe-high');
415
- } else if (sharpe > 1.0) {
416
- btn.classList.add('success');
417
- } else {
418
- btn.classList.add('sharpe-low');
419
- }
420
-
421
- const alphaId = data.result.id;
422
- const alphaUrl = `https://platform.worldquantbrain.com/alpha/${alphaId}`;
423
-
424
- // Determine text color for link based on background
425
- const linkColor = (sharpe <= 1.0) ? 'black' : 'white';
426
-
427
- btn.innerHTML = `夏普: ${res.sharpe.toFixed(2)} | 收益: ${(res.returns * 100).toFixed(1)}% | <a href="${alphaUrl}" target="_blank" style="color: ${linkColor}; text-decoration: underline;" onclick="event.stopPropagation()">${alphaId}</a>`;
428
- btn.title = `ID: ${alphaId}\n换手率: ${res.turnover}`;
429
-
430
- // Remove onclick to prevent re-simulation
431
- btn.removeAttribute('onclick');
432
- btn.style.cursor = 'default';
433
- } else {
434
- throw new Error(data.message);
435
- }
436
- } catch (e) {
437
- btn.classList.remove('simulating');
438
- btn.classList.add('error');
439
- btn.textContent = '错误';
440
- btn.title = e.message;
441
- console.error("Simulation Error Details:", e);
442
- alert('回测失败: ' + e.message);
443
- }
444
- }
445
-
446
- function downloadResults() {
447
- // Flatten the list to get all simulatable payloads
448
- const allPayloads = [];
449
- analyzedAlphas.forEach(alpha => {
450
- alpha.variants.forEach(v => {
451
- // Add some metadata to the payload if useful, or just keep it clean
452
- const p = JSON.parse(JSON.stringify(v.simulation_payload));
453
- // p._origin_alpha_id = alpha.id; // Removed as requested
454
- allPayloads.push(p);
455
- });
456
- });
457
-
458
- const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(allPayloads, null, 2));
459
- const downloadAnchorNode = document.createElement('a');
460
- downloadAnchorNode.setAttribute("href", dataStr);
461
- downloadAnchorNode.setAttribute("download", "simulatable_alphas.json");
462
- document.body.appendChild(downloadAnchorNode);
463
- downloadAnchorNode.click();
464
- downloadAnchorNode.remove();
465
- }
466
-
467
- async function queueAllSimulations() {
468
- const buttons = document.querySelectorAll('.variant-btn');
469
- const queueBtn = document.getElementById('queueBtn');
470
-
471
- if (buttons.length === 0) {
472
- alert('没有可回测的变体');
473
- return;
474
- }
475
-
476
- if (!confirm(`确定要开始 ${buttons.length} 个变体的排队回测吗?这可能需要一些时间。`)) {
477
- return;
478
- }
479
-
480
- queueBtn.disabled = true;
481
- const originalText = queueBtn.textContent;
482
- queueBtn.textContent = '正在排队中... (请勿关闭页面)';
483
-
484
- let count = 0;
485
- for (const btn of buttons) {
486
- // Skip if already running or done
487
- if (btn.classList.contains('simulating') || btn.classList.contains('success')) {
488
- continue;
489
- }
490
-
491
- // Trigger click to start simulation
492
- btn.click();
493
- count++;
494
-
495
- // Update button text to show progress
496
- queueBtn.textContent = `正在排队... (${count}/${buttons.length})`;
497
-
498
- // Wait 500ms between requests to avoid rate limiting
499
- await new Promise(r => setTimeout(r, 500));
500
- }
501
-
502
- queueBtn.textContent = '排队完成';
503
- setTimeout(() => {
504
- queueBtn.disabled = false;
505
- queueBtn.textContent = originalText;
506
- }, 2000);
507
- }
508
- </script>
509
- <script src="{{ url_for('static', filename='usage_widget.js') }}"></script>
510
- </body>
511
- </html>