cnhkmcp 2.1.3__py3-none-any.whl → 2.1.5__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.
- cnhkmcp/__init__.py +126 -0
- 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 +38 -0
- 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
- 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 +6 -0
- 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 +1514 -0
- 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 +157 -0
- 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 +132 -0
- 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 +99 -0
- 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 +180 -0
- 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
- 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
- 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/001_10_Steps_to_Start_on_BRAIN_documentation.json +14 -0
- 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/001_Intermediate_Pack_-_Improve_your_Alpha_2_2_documentation.json +174 -0
- 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/001_Intermediate_Pack_-_Understand_Results_1_2_documentation.json +167 -0
- 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/001_Introduction_to_Alphas_documentation.json +145 -0
- 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/001_Introduction_to_BRAIN_Expression_Language_documentation.json +107 -0
- 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/001_WorldQuant_Challenge_documentation.json +56 -0
- 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/001__Read_this_First_-_Starter_Pack_documentation.json +404 -0
- 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/002_How_to_choose_the_Simulation_Settings_documentation.json +268 -0
- 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/002_Simulate_your_first_Alpha_documentation.json +88 -0
- 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/002__Alpha_Examples_for_Beginners_documentation.json +254 -0
- 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/002__Alpha_Examples_for_Bronze_Users_documentation.json +114 -0
- 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/002__Alpha_Examples_for_Silver_Users_documentation.json +79 -0
- 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/002__How_BRAIN_works_documentation.json +184 -0
- 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/003_Clear_these_tests_before_submitting_an_Alpha_documentation.json +388 -0
- 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/003_Parameters_in_the_Simulation_results_documentation.json +243 -0
- 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/004_Group_Data_Fields_documentation.json +69 -0
- 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/004_How_to_use_the_Data_Explorer_documentation.json +142 -0
- 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/004_Model77_dataset_documentation.json +14 -0
- 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/004_Sentiment1_dataset_documentation.json +14 -0
- 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/004_Understanding_Data_in_BRAIN_Key_Concepts_and_Tips_documentation.json +182 -0
- 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/004_Vector_Data_Fields_documentation.json +30 -0
- 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/005_Crowding_Risk-Neutralized_Alphas_documentation.json +64 -0
- 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/005_D0_documentation.json +66 -0
- 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/005_Double_Neutralization_documentation.json +53 -0
- 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/005_Fast_D1_Documentation_documentation.json +304 -0
- 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/005_Investability_Constrained_Metrics_documentation.json +129 -0
- 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/005_Must-read_posts_How_to_improve_your_Alphas_documentation.json +14 -0
- 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/005_Neutralization_documentation.json +29 -0
- 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/005_RAM_Risk-Neutralized_Alphas_documentation.json +64 -0
- 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/005_Risk_Neutralization_Default_setting_documentation.json +75 -0
- 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/005_Risk_Neutralized_Alphas_documentation.json +171 -0
- 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/005_Statistical_Risk-Neutralized_Alphas_documentation.json +51 -0
- 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/006_EUR_TOP2500_Universe_documentation.json +35 -0
- 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/006_GLB_TOPDIV3000_Universe_documentation.json +48 -0
- 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/006_Getting_Started_China_Research_for_Consultants_Gold_documentation.json +142 -0
- 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/006_Getting_started_on_Illiquid_Universes_Gold_documentation.json +46 -0
- 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/006_Getting_started_with_USA_TOPSP500_universe_Gold_documentation.json +62 -0
- 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/006_Global_Alphas_Gold_documentation.json +66 -0
- 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/006_India_Alphas_documentation.json +35 -0
- 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/007_Consultant_Dos_and_Don_ts_documentation.json +35 -0
- 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/007_Consultant_Features_documentation.json +239 -0
- 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/007_Consultant_Simulation_Features_documentation.json +149 -0
- 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/007_Consultant_Submission_Tests_documentation.json +363 -0
- 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/007_Finding_Consultant_Alphas_documentation.json +333 -0
- 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/007_Power_Pool_Alphas_documentation.json +14 -0
- 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/007_Research_Advisory_Program_documentation.json +35 -0
- 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/007_Starting_Guide_for_Research_Consultants_documentation.json +14 -0
- 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/007_Visualization_Tool_documentation.json +99 -0
- 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/007_Your_Advisor_-_Kunqi_Jiang_documentation.json +53 -0
- 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/007__Brain_Genius_documentation.json +288 -0
- 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/007__Single_Dataset_Alphas_documentation.json +41 -0
- 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/008_Advisory_Theme_Calendar_documentation.json +14 -0
- 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/008_Multiplier_Rules_documentation.json +14 -0
- 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/008_Overview_of_Themes_documentation.json +14 -0
- 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/008_Theme_Calendar_documentation.json +14 -0
- 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/009_Combo_Expression_documentation.json +272 -0
- 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/009_Global_SuperAlphas_documentation.json +14 -0
- 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/009_Helpful_Tips_documentation.json +58 -0
- 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/009_Selection_Expression_documentation.json +1546 -0
- 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/009_SuperAlpha_Operators_documentation.json +890 -0
- 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/009_SuperAlpha_Results_documentation.json +83 -0
- 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/009_What_is_a_SuperAlpha_documentation.json +261 -0
- 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/010_BRAIN_API_documentation.json +515 -0
- 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/010_Documentation_for_ACE_API_Library_Gold_documentation.json +27 -0
- 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/010__Understanding_simulation_limits_documentation.json +210 -0
- 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/arithmetic_operators.json +209 -0
- 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/cross_sectional_operators.json +98 -0
- 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/group_operators.json +121 -0
- 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/logical_operators.json +145 -0
- 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/reduce_operators.json +156 -0
- 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/special_operators.json +35 -0
- 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 +1 -0
- 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/time_series_operators.json +386 -0
- 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/transformational_operators.json +61 -0
- 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/vector_operators.json +38 -0
- 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 +576 -0
- 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 +281 -0
- 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 +408 -0
- 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 +7 -0
- 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 +3 -0
- 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 +302 -0
- 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 +1 -0
- 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
- 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 +265 -0
- cnhkmcp/untracked/APP/.gitignore +32 -0
- cnhkmcp/untracked/APP/MODULAR_STRUCTURE.md +112 -0
- cnhkmcp/untracked/APP/README.md +309 -0
- cnhkmcp/untracked/APP/Tranformer/Transformer.py +4989 -0
- cnhkmcp/untracked/APP/Tranformer/ace.log +0 -0
- cnhkmcp/untracked/APP/Tranformer/ace_lib.py +1514 -0
- cnhkmcp/untracked/APP/Tranformer/helpful_functions.py +180 -0
- cnhkmcp/untracked/APP/Tranformer/output/Alpha_candidates.json +7187 -0
- cnhkmcp/untracked/APP/Tranformer/output/Alpha_candidates_/321/207/320/264/342/225/221/321/204/342/225/233/320/233.json +654 -0
- cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_error.json +1 -0
- cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_success.json +47312 -0
- 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 +22 -0
- cnhkmcp/untracked/APP/Tranformer/parsetab.py +60 -0
- cnhkmcp/untracked/APP/Tranformer/template_summary.txt +3182 -0
- cnhkmcp/untracked/APP/Tranformer/transformer_config.json +7 -0
- cnhkmcp/untracked/APP/Tranformer/validator.py +889 -0
- cnhkmcp/untracked/APP/ace.log +69 -0
- cnhkmcp/untracked/APP/ace_lib.py +1514 -0
- cnhkmcp/untracked/APP/blueprints/__init__.py +6 -0
- cnhkmcp/untracked/APP/blueprints/feature_engineering.py +347 -0
- cnhkmcp/untracked/APP/blueprints/idea_house.py +221 -0
- cnhkmcp/untracked/APP/blueprints/inspiration_house.py +432 -0
- cnhkmcp/untracked/APP/blueprints/paper_analysis.py +570 -0
- cnhkmcp/untracked/APP/custom_templates/templates.json +1257 -0
- cnhkmcp/untracked/APP/give_me_idea/BRAIN_Alpha_Template_Expert_SystemPrompt.md +400 -0
- cnhkmcp/untracked/APP/give_me_idea/ace_lib.py +1514 -0
- cnhkmcp/untracked/APP/give_me_idea/alpha_data_specific_template_master.py +252 -0
- cnhkmcp/untracked/APP/give_me_idea/fetch_all_datasets.py +157 -0
- cnhkmcp/untracked/APP/give_me_idea/fetch_all_operators.py +99 -0
- cnhkmcp/untracked/APP/give_me_idea/helpful_functions.py +180 -0
- cnhkmcp/untracked/APP/give_me_idea/what_is_Alpha_template.md +11 -0
- cnhkmcp/untracked/APP/helpful_functions.py +180 -0
- cnhkmcp/untracked/APP/hkSimulator/ace_lib.py +1501 -0
- cnhkmcp/untracked/APP/hkSimulator/autosimulator.py +447 -0
- cnhkmcp/untracked/APP/hkSimulator/helpful_functions.py +180 -0
- cnhkmcp/untracked/APP/mirror_config.txt +20 -0
- cnhkmcp/untracked/APP/operaters.csv +129 -0
- cnhkmcp/untracked/APP/requirements.txt +53 -0
- cnhkmcp/untracked/APP/run_app.bat +28 -0
- cnhkmcp/untracked/APP/run_app.sh +34 -0
- cnhkmcp/untracked/APP/setup_tsinghua.bat +39 -0
- cnhkmcp/untracked/APP/setup_tsinghua.sh +43 -0
- cnhkmcp/untracked/APP/simulator/alpha_submitter.py +404 -0
- cnhkmcp/untracked/APP/simulator/simulator_wqb.py +618 -0
- cnhkmcp/untracked/APP/ssrn-3332513.pdf +109188 -19
- cnhkmcp/untracked/APP/static/brain.js +589 -0
- cnhkmcp/untracked/APP/static/decoder.js +1540 -0
- cnhkmcp/untracked/APP/static/feature_engineering.js +1729 -0
- cnhkmcp/untracked/APP/static/idea_house.js +937 -0
- cnhkmcp/untracked/APP/static/inspiration.js +465 -0
- cnhkmcp/untracked/APP/static/inspiration_house.js +868 -0
- cnhkmcp/untracked/APP/static/paper_analysis.js +390 -0
- cnhkmcp/untracked/APP/static/script.js +3082 -0
- cnhkmcp/untracked/APP/static/simulator.js +597 -0
- cnhkmcp/untracked/APP/static/styles.css +3127 -0
- cnhkmcp/untracked/APP/static/usage_widget.js +508 -0
- cnhkmcp/untracked/APP/templates/alpha_inspector.html +511 -0
- cnhkmcp/untracked/APP/templates/feature_engineering.html +960 -0
- cnhkmcp/untracked/APP/templates/idea_house.html +564 -0
- cnhkmcp/untracked/APP/templates/index.html +932 -0
- cnhkmcp/untracked/APP/templates/inspiration_house.html +861 -0
- cnhkmcp/untracked/APP/templates/paper_analysis.html +91 -0
- cnhkmcp/untracked/APP/templates/simulator.html +343 -0
- cnhkmcp/untracked/APP/templates/transformer_web.html +580 -0
- cnhkmcp/untracked/APP/usage.md +351 -0
- 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 +1514 -0
- 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 +712 -0
- 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 +180 -0
- 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 +2460 -0
- cnhkmcp/untracked/__init__.py +0 -0
- cnhkmcp/untracked/arXiv_API_Tool_Manual.md +490 -0
- cnhkmcp/untracked/arxiv_api.py +229 -0
- cnhkmcp/untracked/back_up/forum_functions.py +998 -0
- cnhkmcp/untracked/back_up/platform_functions.py +2886 -0
- cnhkmcp/untracked/brain-consultant.md +31 -0
- cnhkmcp/untracked/forum_functions.py +407 -0
- 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 +407 -0
- 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 +2601 -0
- 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 +31 -0
- 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 +101 -0
- 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 +190 -0
- cnhkmcp/untracked/platform_functions.py +2601 -0
- cnhkmcp/untracked/sample_mcp_config.json +11 -0
- cnhkmcp/untracked/user_config.json +31 -0
- 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 +202 -0
- 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 +56 -0
- 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 +194 -0
- 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 +101 -0
- 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 +436 -0
- 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 +128 -0
- 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 +192 -0
- {cnhkmcp-2.1.3.dist-info → cnhkmcp-2.1.5.dist-info}/METADATA +1 -1
- cnhkmcp-2.1.5.dist-info/RECORD +192 -0
- cnhkmcp-2.1.5.dist-info/top_level.txt +1 -0
- cnhkmcp-2.1.3.dist-info/RECORD +0 -6
- cnhkmcp-2.1.3.dist-info/top_level.txt +0 -1
- {cnhkmcp-2.1.3.dist-info → cnhkmcp-2.1.5.dist-info}/WHEEL +0 -0
- {cnhkmcp-2.1.3.dist-info → cnhkmcp-2.1.5.dist-info}/entry_points.txt +0 -0
- {cnhkmcp-2.1.3.dist-info → cnhkmcp-2.1.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enhanced Alpha Template Generator Script
|
|
3
|
+
|
|
4
|
+
This script generates alpha templates with interactive user input for:
|
|
5
|
+
- JSON file path selection
|
|
6
|
+
- User authentication
|
|
7
|
+
- Simulation parameters
|
|
8
|
+
- Multi-simulation mode support
|
|
9
|
+
- Real-time log monitoring
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
import wqb
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
16
|
+
import getpass
|
|
17
|
+
import threading
|
|
18
|
+
import time
|
|
19
|
+
import sys
|
|
20
|
+
import msvcrt # For Windows password input with asterisks
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
# FIX: Change working directory to script location to ensure logs are created in the right place
|
|
24
|
+
# This prevents the "Permission denied" error when trying to create logs in system directories
|
|
25
|
+
# The wqb.wqb_logger() function creates log files relative to the current working directory
|
|
26
|
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
27
|
+
try:
|
|
28
|
+
os.chdir(script_dir)
|
|
29
|
+
print(f"📁 工作目录已设置为: {os.getcwd()}")
|
|
30
|
+
print(f"📝 日志文件将创建在: {os.getcwd()}")
|
|
31
|
+
|
|
32
|
+
# Verify the directory is writable
|
|
33
|
+
if not os.access(script_dir, os.W_OK):
|
|
34
|
+
print(f"⚠️ 警告: 目录 {script_dir} 不可写,日志可能无法创建")
|
|
35
|
+
else:
|
|
36
|
+
print(f"✅ 目录 {script_dir} 可写,日志将正常创建")
|
|
37
|
+
|
|
38
|
+
except Exception as e:
|
|
39
|
+
print(f"⚠️ 警告: 无法更改工作目录到 {script_dir}: {e}")
|
|
40
|
+
print(f"📝 日志文件将创建在当前工作目录: {os.getcwd()}")
|
|
41
|
+
|
|
42
|
+
def get_password_with_asterisks(prompt):
|
|
43
|
+
"""Get password input with asterisks shown for each character"""
|
|
44
|
+
print(prompt, end='', flush=True)
|
|
45
|
+
password = ""
|
|
46
|
+
|
|
47
|
+
while True:
|
|
48
|
+
char = msvcrt.getch()
|
|
49
|
+
|
|
50
|
+
# Handle Enter key (carriage return)
|
|
51
|
+
if char == b'\r':
|
|
52
|
+
print() # New line
|
|
53
|
+
break
|
|
54
|
+
# Handle Backspace
|
|
55
|
+
elif char == b'\x08':
|
|
56
|
+
if len(password) > 0:
|
|
57
|
+
password = password[:-1]
|
|
58
|
+
# Move cursor back, print space, move cursor back again
|
|
59
|
+
print('\b \b', end='', flush=True)
|
|
60
|
+
# Handle Ctrl+C
|
|
61
|
+
elif char == b'\x03':
|
|
62
|
+
print()
|
|
63
|
+
raise KeyboardInterrupt
|
|
64
|
+
# Handle regular characters
|
|
65
|
+
else:
|
|
66
|
+
try:
|
|
67
|
+
# Convert bytes to string
|
|
68
|
+
char_str = char.decode('utf-8')
|
|
69
|
+
if char_str.isprintable():
|
|
70
|
+
password += char_str
|
|
71
|
+
print('*', end='', flush=True)
|
|
72
|
+
except UnicodeDecodeError:
|
|
73
|
+
pass # Ignore non-printable characters
|
|
74
|
+
|
|
75
|
+
return password
|
|
76
|
+
|
|
77
|
+
def get_json_filepath():
|
|
78
|
+
"""Ask user to input the directory/filepath of expressions_with_settings.json"""
|
|
79
|
+
while True:
|
|
80
|
+
print("\n" + "="*60)
|
|
81
|
+
print("JSON 文件配置")
|
|
82
|
+
print("="*60)
|
|
83
|
+
filepath = input("请复制粘贴 expressions_with_settings.json (即以json格式储存的带有setting的表达式列表)的目录或完整路径: ").strip()
|
|
84
|
+
|
|
85
|
+
# Remove quotes if user copied with quotes
|
|
86
|
+
filepath = filepath.strip('"').strip("'")
|
|
87
|
+
|
|
88
|
+
# Check if it's a directory and try to find the file
|
|
89
|
+
if os.path.isdir(filepath):
|
|
90
|
+
json_path = os.path.join(filepath, "expressions_with_settings.json")
|
|
91
|
+
else:
|
|
92
|
+
json_path = filepath
|
|
93
|
+
|
|
94
|
+
# Verify file exists
|
|
95
|
+
if os.path.exists(json_path):
|
|
96
|
+
try:
|
|
97
|
+
with open(json_path, 'r', encoding='utf-8') as f:
|
|
98
|
+
data = json.load(f)
|
|
99
|
+
print(f"✓ 成功加载 JSON 文件: {json_path}")
|
|
100
|
+
return json_path, data
|
|
101
|
+
except json.JSONDecodeError:
|
|
102
|
+
print("❌ 错误: JSON 文件格式无效,请检查文件。")
|
|
103
|
+
except Exception as e:
|
|
104
|
+
print(f"❌ 读取文件错误: {e}")
|
|
105
|
+
else:
|
|
106
|
+
print("❌ 错误: 文件未找到,请检查路径后重试。")
|
|
107
|
+
|
|
108
|
+
def get_user_credentials():
|
|
109
|
+
"""Ask user for brain username and password with asterisk password input"""
|
|
110
|
+
print("\n" + "="*60)
|
|
111
|
+
print("BRAIN 身份验证")
|
|
112
|
+
print("="*60)
|
|
113
|
+
|
|
114
|
+
username = input("请输入您的 BRAIN 用户名: ").strip()
|
|
115
|
+
password = get_password_with_asterisks("请输入您的 BRAIN 密码 (显示为 *): ")
|
|
116
|
+
|
|
117
|
+
return username, password
|
|
118
|
+
|
|
119
|
+
def test_authentication(username, password):
|
|
120
|
+
"""Test authentication and return session if successful"""
|
|
121
|
+
print("\n" + "="*60)
|
|
122
|
+
print("API连通验证")
|
|
123
|
+
print("="*60)
|
|
124
|
+
|
|
125
|
+
try:
|
|
126
|
+
logger = wqb.wqb_logger()
|
|
127
|
+
wqbs = wqb.WQBSession((username, password), logger=logger)
|
|
128
|
+
|
|
129
|
+
# Test connection
|
|
130
|
+
resp = wqbs.locate_field('open')
|
|
131
|
+
print(f"连接测试结果: resp.ok = {resp.ok}")
|
|
132
|
+
|
|
133
|
+
if resp.ok:
|
|
134
|
+
print("✓ 身份验证成功!")
|
|
135
|
+
return wqbs, logger
|
|
136
|
+
else:
|
|
137
|
+
print("❌ 身份验证失败,请检查您的用户名和密码。")
|
|
138
|
+
return None, None
|
|
139
|
+
|
|
140
|
+
except Exception as e:
|
|
141
|
+
print(f"❌ 身份验证错误: {e}")
|
|
142
|
+
return None, None
|
|
143
|
+
|
|
144
|
+
def get_simulation_parameters(expressions_count, json_path):
|
|
145
|
+
"""Get simulation parameters from user with validation"""
|
|
146
|
+
print("\n" + "="*60)
|
|
147
|
+
print("回测参数设置")
|
|
148
|
+
print("="*60)
|
|
149
|
+
print(f"JSON 中的表达式总数: {expressions_count}")
|
|
150
|
+
|
|
151
|
+
# Get starting position
|
|
152
|
+
while True:
|
|
153
|
+
try:
|
|
154
|
+
where_to_start = int(input(f"从列表中第几个表达式开始 (0 到 {expressions_count-1}): "))
|
|
155
|
+
if 0 <= where_to_start < expressions_count:
|
|
156
|
+
if where_to_start > 0:
|
|
157
|
+
print(f"\n⚠️ 警告: 原始 JSON 文件将被直接覆盖!")
|
|
158
|
+
print(f"📝 原始文件: {expressions_count} 个表达式")
|
|
159
|
+
print(f"🔪 切割后: {expressions_count - where_to_start} 个表达式")
|
|
160
|
+
print(f"📂 文件位置: {json_path}")
|
|
161
|
+
print(f"\n🚨 重要提示: 如果您不希望覆盖原始文件,请立即关闭终端并手动备份文件!")
|
|
162
|
+
print(f"⏰ 5秒后将继续执行覆盖操作...")
|
|
163
|
+
|
|
164
|
+
# Give user 5 seconds to think/close terminal
|
|
165
|
+
import time
|
|
166
|
+
for i in range(5, 0, -1):
|
|
167
|
+
print(f"倒计时: {i} 秒...", end='\r')
|
|
168
|
+
time.sleep(1)
|
|
169
|
+
print(" ") # Clear countdown line
|
|
170
|
+
|
|
171
|
+
confirm = input("(继续程序,开始回测y/返回并重选列表起始位置n): ").lower().strip()
|
|
172
|
+
if confirm != 'y':
|
|
173
|
+
print("请重新选择表达式列表起始位置。")
|
|
174
|
+
continue
|
|
175
|
+
break
|
|
176
|
+
else:
|
|
177
|
+
print(f"❌ 起始位置无效,必须在 0 到 {expressions_count-1} 之间")
|
|
178
|
+
except ValueError:
|
|
179
|
+
print("❌ 请输入有效数字。")
|
|
180
|
+
|
|
181
|
+
# Get concurrent count
|
|
182
|
+
while True:
|
|
183
|
+
try:
|
|
184
|
+
concurrent_count = int(input("请输入并发回测数量 (最小值 1): "))
|
|
185
|
+
if concurrent_count >= 1:
|
|
186
|
+
break
|
|
187
|
+
else:
|
|
188
|
+
print("❌ 并发数量必须大于等于 1。")
|
|
189
|
+
except ValueError:
|
|
190
|
+
print("❌ 请输入有效数字。")
|
|
191
|
+
|
|
192
|
+
return where_to_start, concurrent_count
|
|
193
|
+
|
|
194
|
+
def cut_json_file(json_path, expressions_with_settings, where_to_start):
|
|
195
|
+
"""Cut the JSON file from the starting point and overwrite the original file"""
|
|
196
|
+
if where_to_start == 0:
|
|
197
|
+
return expressions_with_settings # No cutting needed
|
|
198
|
+
|
|
199
|
+
# Cut the expressions list
|
|
200
|
+
cut_expressions = expressions_with_settings[where_to_start:]
|
|
201
|
+
|
|
202
|
+
# Overwrite the original JSON file
|
|
203
|
+
try:
|
|
204
|
+
with open(json_path, 'w', encoding='utf-8') as f:
|
|
205
|
+
json.dump(cut_expressions, f, ensure_ascii=False, indent=2)
|
|
206
|
+
print(f"✓ 原始 JSON 文件已被覆盖")
|
|
207
|
+
print(f"📊 新文件包含 {len(cut_expressions)} 个表达式")
|
|
208
|
+
return cut_expressions
|
|
209
|
+
except Exception as e:
|
|
210
|
+
print(f"❌ 覆盖 JSON 文件失败: {e}")
|
|
211
|
+
print(f"⚠️ 将使用原始数据继续运行")
|
|
212
|
+
return expressions_with_settings
|
|
213
|
+
|
|
214
|
+
def shuffle_json_file(json_path, expressions_with_settings):
|
|
215
|
+
"""Randomly shuffle the JSON elements and overwrite the file"""
|
|
216
|
+
import random
|
|
217
|
+
|
|
218
|
+
# Create a copy and shuffle it
|
|
219
|
+
shuffled_expressions = expressions_with_settings.copy()
|
|
220
|
+
random.shuffle(shuffled_expressions)
|
|
221
|
+
|
|
222
|
+
# Overwrite the JSON file with shuffled data
|
|
223
|
+
try:
|
|
224
|
+
with open(json_path, 'w', encoding='utf-8') as f:
|
|
225
|
+
json.dump(shuffled_expressions, f, ensure_ascii=False, indent=2)
|
|
226
|
+
print(f"✓ JSON 文件已随机打乱并覆盖")
|
|
227
|
+
print(f"🔀 已打乱 {len(shuffled_expressions)} 个表达式的顺序")
|
|
228
|
+
return shuffled_expressions
|
|
229
|
+
except Exception as e:
|
|
230
|
+
print(f"❌ 打乱 JSON 文件失败: {e}")
|
|
231
|
+
print(f"⚠️ 将使用原始顺序继续运行")
|
|
232
|
+
return expressions_with_settings
|
|
233
|
+
|
|
234
|
+
def get_random_shuffle_choice():
|
|
235
|
+
"""Ask user if they want to randomly shuffle the expressions"""
|
|
236
|
+
print("\n" + "="*60)
|
|
237
|
+
print("随机模式选择")
|
|
238
|
+
print("="*60)
|
|
239
|
+
print("是否要随机打乱表达式顺序?")
|
|
240
|
+
print("💡 这将改变表达式在文件中的排列顺序,以达到随机回测的目的")
|
|
241
|
+
|
|
242
|
+
while True:
|
|
243
|
+
choice = input("选择随机模式? (y/n): ").lower().strip()
|
|
244
|
+
if choice in ['y', 'n']:
|
|
245
|
+
return choice == 'y'
|
|
246
|
+
else:
|
|
247
|
+
print("❌ 请输入 y 或 n")
|
|
248
|
+
|
|
249
|
+
def get_multi_simulation_choice():
|
|
250
|
+
"""Ask user if they want to use multi-simulation mode"""
|
|
251
|
+
print("\n" + "="*60)
|
|
252
|
+
print("多重回测(multi-simulatioin)模式选择")
|
|
253
|
+
print("="*60)
|
|
254
|
+
print("是否要使用多重回测(multi-simulatioin)模式?")
|
|
255
|
+
print("💡 多重回测(multi-simulatioin)可以将多个alpha组合在一个回测槽中运行")
|
|
256
|
+
|
|
257
|
+
while True:
|
|
258
|
+
choice = input("使用多重回测(multi-simulatioin)模式? (y/n): ").lower().strip()
|
|
259
|
+
if choice in ['y', 'n']:
|
|
260
|
+
return choice == 'y'
|
|
261
|
+
else:
|
|
262
|
+
print("❌ 请输入 y 或 n")
|
|
263
|
+
|
|
264
|
+
def get_alpha_count_per_slot():
|
|
265
|
+
"""Ask user how many alphas to put in one multi-simulation slot"""
|
|
266
|
+
print("\n" + "="*60)
|
|
267
|
+
print("多重回测(multi-simulatioin)槽配置")
|
|
268
|
+
print("="*60)
|
|
269
|
+
print("每个多重回测(multi-simulatioin)槽中放置多少个alpha?")
|
|
270
|
+
print("💡 范围: 2-10 个alpha")
|
|
271
|
+
|
|
272
|
+
while True:
|
|
273
|
+
try:
|
|
274
|
+
alpha_count = int(input("每个槽的alpha数量 (2-10): "))
|
|
275
|
+
if 2 <= alpha_count <= 10:
|
|
276
|
+
return alpha_count
|
|
277
|
+
else:
|
|
278
|
+
print("❌ 数量必须在 2 到 10 之间")
|
|
279
|
+
except ValueError:
|
|
280
|
+
print("❌ 请输入有效数字。")
|
|
281
|
+
|
|
282
|
+
def monitor_log_file(logger, stop_event, use_multi_sim=False, alpha_count_per_slot=None):
|
|
283
|
+
"""Monitor log file and print new lines in real-time"""
|
|
284
|
+
print("\n📊 开始监控日志文件...")
|
|
285
|
+
|
|
286
|
+
# Get current directory to look for log files
|
|
287
|
+
current_dir = os.getcwd()
|
|
288
|
+
log_file_path = None
|
|
289
|
+
|
|
290
|
+
# First, try to find any existing wqb log files (including older ones)
|
|
291
|
+
print("🔍 查找 WQB 日志文件...")
|
|
292
|
+
|
|
293
|
+
# Look for any wqb*.log files in current directory
|
|
294
|
+
wqb_files = []
|
|
295
|
+
try:
|
|
296
|
+
for file in os.listdir(current_dir):
|
|
297
|
+
if file.startswith('wqb') and file.endswith('.log'):
|
|
298
|
+
file_path = os.path.join(current_dir, file)
|
|
299
|
+
wqb_files.append((file_path, os.path.getmtime(file_path)))
|
|
300
|
+
except Exception as e:
|
|
301
|
+
print(f"⚠️ 扫描目录失败: {e}")
|
|
302
|
+
return
|
|
303
|
+
|
|
304
|
+
if wqb_files:
|
|
305
|
+
# Sort by modification time, get the newest one
|
|
306
|
+
log_file_path = sorted(wqb_files, key=lambda x: x[1], reverse=True)[0][0]
|
|
307
|
+
print(f"✓ 监控已找到的最新日志文件: {log_file_path}")
|
|
308
|
+
else:
|
|
309
|
+
# Wait for new log file to be created
|
|
310
|
+
print("等待新的 WQB 日志文件创建...")
|
|
311
|
+
start_time = time.time()
|
|
312
|
+
|
|
313
|
+
while not stop_event.is_set() and (time.time() - start_time) < 30: # Wait max 30 seconds
|
|
314
|
+
try:
|
|
315
|
+
for file in os.listdir(current_dir):
|
|
316
|
+
if file.startswith('wqb') and file.endswith('.log'):
|
|
317
|
+
file_path = os.path.join(current_dir, file)
|
|
318
|
+
# Check if file was created recently (within last 120 seconds)
|
|
319
|
+
if os.path.getctime(file_path) > (time.time() - 120):
|
|
320
|
+
log_file_path = file_path
|
|
321
|
+
break
|
|
322
|
+
except Exception:
|
|
323
|
+
pass
|
|
324
|
+
|
|
325
|
+
if log_file_path:
|
|
326
|
+
break
|
|
327
|
+
time.sleep(1)
|
|
328
|
+
|
|
329
|
+
if not log_file_path:
|
|
330
|
+
print("⚠️ 未找到 WQB 日志文件,日志监控已禁用。")
|
|
331
|
+
print("💡 提示: 日志文件通常在开始回测后才会创建")
|
|
332
|
+
return
|
|
333
|
+
else:
|
|
334
|
+
print(f"✓ 找到新日志文件: {log_file_path}")
|
|
335
|
+
|
|
336
|
+
if stop_event.is_set():
|
|
337
|
+
return
|
|
338
|
+
|
|
339
|
+
print("="*60)
|
|
340
|
+
|
|
341
|
+
# Display multi-simulation information if applicable
|
|
342
|
+
if use_multi_sim and alpha_count_per_slot:
|
|
343
|
+
print("📌 重要提示:")
|
|
344
|
+
print(f"以下是multi simulation的记录,你的设计是1个multi simulation中有{alpha_count_per_slot}个alpha,")
|
|
345
|
+
print(f"因此需将实际回测数乘以该乘数,才得到实际已完成的Alpha个数。")
|
|
346
|
+
print("="*60)
|
|
347
|
+
|
|
348
|
+
try:
|
|
349
|
+
# Start monitoring from current end of file
|
|
350
|
+
with open(log_file_path, 'r', encoding='utf-8') as f:
|
|
351
|
+
# Go to end of file
|
|
352
|
+
f.seek(0, 2)
|
|
353
|
+
|
|
354
|
+
while not stop_event.is_set():
|
|
355
|
+
line = f.readline()
|
|
356
|
+
if line:
|
|
357
|
+
# Clean up the log line and print it
|
|
358
|
+
clean_line = line.rstrip()
|
|
359
|
+
if clean_line: # Only print non-empty lines
|
|
360
|
+
print(f"[日志] {clean_line}")
|
|
361
|
+
else:
|
|
362
|
+
time.sleep(0.2)
|
|
363
|
+
except Exception as e:
|
|
364
|
+
print(f"⚠️ 监控日志文件时出错: {e}")
|
|
365
|
+
|
|
366
|
+
async def automated_main(json_file_content, username, password, start_position=0, concurrent_count=3,
|
|
367
|
+
random_shuffle=False, use_multi_sim=False, alpha_count_per_slot=3):
|
|
368
|
+
"""Automated main function for web interface - takes all parameters at once"""
|
|
369
|
+
try:
|
|
370
|
+
print("🧠 BRAIN Alpha 模板回测器 (自动模式)")
|
|
371
|
+
print("="*60)
|
|
372
|
+
|
|
373
|
+
# Parse JSON content directly
|
|
374
|
+
import json
|
|
375
|
+
expressions_with_settings = json.loads(json_file_content)
|
|
376
|
+
expressions_count = len(expressions_with_settings)
|
|
377
|
+
|
|
378
|
+
print(f"📊 已加载 {expressions_count} 个 alpha 配置")
|
|
379
|
+
|
|
380
|
+
# Setup logger and session
|
|
381
|
+
logger = wqb.wqb_logger()
|
|
382
|
+
wqbs = wqb.WQBSession((username, password), logger=logger)
|
|
383
|
+
|
|
384
|
+
# Test connection
|
|
385
|
+
resp = wqbs.locate_field('open')
|
|
386
|
+
print(f"连接测试结果: resp.ok = {resp.ok}")
|
|
387
|
+
|
|
388
|
+
if not resp.ok:
|
|
389
|
+
print("❌ 身份验证失败")
|
|
390
|
+
return {"success": False, "error": "Authentication failed"}
|
|
391
|
+
|
|
392
|
+
print("✅ 身份验证成功!")
|
|
393
|
+
|
|
394
|
+
# Process expressions based on parameters
|
|
395
|
+
if start_position > 0:
|
|
396
|
+
expressions_with_settings = expressions_with_settings[start_position:]
|
|
397
|
+
print(f"🔪 已从位置 {start_position} 开始切割,剩余 {len(expressions_with_settings)} 个表达式")
|
|
398
|
+
|
|
399
|
+
if random_shuffle:
|
|
400
|
+
import random
|
|
401
|
+
random.shuffle(expressions_with_settings)
|
|
402
|
+
print(f"🔀 已随机打乱 {len(expressions_with_settings)} 个表达式的顺序")
|
|
403
|
+
|
|
404
|
+
if use_multi_sim:
|
|
405
|
+
# Convert to multi-alphas format
|
|
406
|
+
original_count = len(expressions_with_settings)
|
|
407
|
+
expressions_with_settings = wqb.to_multi_alphas(expressions_with_settings, alpha_count_per_slot)
|
|
408
|
+
print(f"✓ 已转换为多重回测(multi-simulatioin)格式")
|
|
409
|
+
print(f"📊 原始表达式数: {original_count}")
|
|
410
|
+
print(f"🎯 每槽alpha数: {alpha_count_per_slot}")
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
# Write multi-simulation info to log
|
|
414
|
+
multi_sim_msg = (f"[MULTI-SIMULATION MODE] 以下是multi simulation的记录,"
|
|
415
|
+
f"你的设计是1个multi simulation中有{alpha_count_per_slot}个alpha,"
|
|
416
|
+
f"因此需将实际回测数乘以该乘数,才得到实际已完成的Alpha个数。")
|
|
417
|
+
logger.info("="*80)
|
|
418
|
+
logger.info(multi_sim_msg)
|
|
419
|
+
logger.info("="*80)
|
|
420
|
+
|
|
421
|
+
print(f"🔄 使用 {concurrent_count} 个并发回测")
|
|
422
|
+
|
|
423
|
+
# Start log monitoring in background
|
|
424
|
+
stop_log_monitor = threading.Event()
|
|
425
|
+
log_thread = threading.Thread(
|
|
426
|
+
target=monitor_log_file,
|
|
427
|
+
args=(logger, stop_log_monitor, use_multi_sim, alpha_count_per_slot),
|
|
428
|
+
daemon=True
|
|
429
|
+
)
|
|
430
|
+
log_thread.start()
|
|
431
|
+
|
|
432
|
+
print("\n" + "="*60)
|
|
433
|
+
print("运行回测")
|
|
434
|
+
print("="*60)
|
|
435
|
+
|
|
436
|
+
if use_multi_sim:
|
|
437
|
+
print("开始多重回测(multi-simulatioin)并发回测...")
|
|
438
|
+
else:
|
|
439
|
+
print("开始并发回测...")
|
|
440
|
+
|
|
441
|
+
try:
|
|
442
|
+
# Run simulations
|
|
443
|
+
resps = await wqbs.concurrent_simulate(
|
|
444
|
+
expressions_with_settings,
|
|
445
|
+
concurrent_count,
|
|
446
|
+
log_gap=10
|
|
447
|
+
)
|
|
448
|
+
finally:
|
|
449
|
+
# Stop log monitoring
|
|
450
|
+
stop_log_monitor.set()
|
|
451
|
+
# Give the log thread a moment to print remaining logs
|
|
452
|
+
time.sleep(0.5)
|
|
453
|
+
|
|
454
|
+
# Collect results
|
|
455
|
+
alpha_ids = []
|
|
456
|
+
successful_count = 0
|
|
457
|
+
failed_count = 0
|
|
458
|
+
|
|
459
|
+
print("\n" + "="*60)
|
|
460
|
+
print("回测结果")
|
|
461
|
+
print("="*60)
|
|
462
|
+
|
|
463
|
+
if use_multi_sim:
|
|
464
|
+
print(f"成功完成 {len(resps)} 个多重回测(multi-simulatioin)槽的回测")
|
|
465
|
+
else:
|
|
466
|
+
print(f"成功完成 {len(resps)} 个回测")
|
|
467
|
+
|
|
468
|
+
print("\nAlpha IDs:")
|
|
469
|
+
# for i, resp in enumerate(resps):
|
|
470
|
+
# try:
|
|
471
|
+
# alpha_id = resp.json()['alpha']
|
|
472
|
+
# alpha_ids.append(alpha_id)
|
|
473
|
+
# successful_count += 1
|
|
474
|
+
# print(f" {i+1:4d}. {alpha_id}")
|
|
475
|
+
# except Exception as e:
|
|
476
|
+
# failed_count += 1
|
|
477
|
+
# print(f" {i+1:4d}. 错误: {e}")
|
|
478
|
+
|
|
479
|
+
print("\n✅ 处理完成!")
|
|
480
|
+
|
|
481
|
+
return {
|
|
482
|
+
"success": True,
|
|
483
|
+
"results": {
|
|
484
|
+
"total": len(resps),
|
|
485
|
+
"successful": successful_count,
|
|
486
|
+
"failed": failed_count,
|
|
487
|
+
"alphaIds": alpha_ids,
|
|
488
|
+
"use_multi_sim": use_multi_sim,
|
|
489
|
+
"alpha_count_per_slot": alpha_count_per_slot if use_multi_sim else None
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
except Exception as e:
|
|
494
|
+
print(f"\n❌ 错误: {e}")
|
|
495
|
+
return {"success": False, "error": str(e)}
|
|
496
|
+
|
|
497
|
+
async def main():
|
|
498
|
+
"""Main function with interactive workflow"""
|
|
499
|
+
print("🧠 BRAIN Alpha 模板回测器")
|
|
500
|
+
print("="*60)
|
|
501
|
+
|
|
502
|
+
# Step 1: Get JSON file and load expressions
|
|
503
|
+
json_path, expressions_with_settings = get_json_filepath()
|
|
504
|
+
expressions_count = len(expressions_with_settings)
|
|
505
|
+
|
|
506
|
+
print(f"\n📊 已从以下位置加载 {expressions_count} 个 alpha 配置:")
|
|
507
|
+
print(f" {json_path}")
|
|
508
|
+
|
|
509
|
+
# Step 2: Get credentials and test authentication
|
|
510
|
+
wqbs = None
|
|
511
|
+
logger = None
|
|
512
|
+
|
|
513
|
+
while wqbs is None:
|
|
514
|
+
username, password = get_user_credentials()
|
|
515
|
+
wqbs, logger = test_authentication(username, password)
|
|
516
|
+
|
|
517
|
+
if wqbs is None:
|
|
518
|
+
retry = input("\n是否要重试? (y/n): ").lower().strip()
|
|
519
|
+
if retry != 'y':
|
|
520
|
+
print("正在退出...")
|
|
521
|
+
return
|
|
522
|
+
|
|
523
|
+
# Step 3: Get simulation parameters
|
|
524
|
+
where_to_start, concurrent_count = get_simulation_parameters(expressions_count, json_path)
|
|
525
|
+
|
|
526
|
+
# Step 3.5: Cut JSON file if needed
|
|
527
|
+
if where_to_start > 0:
|
|
528
|
+
print(f"\n🔪 正在切割 JSON 文件...")
|
|
529
|
+
expressions_with_settings = cut_json_file(json_path, expressions_with_settings, where_to_start)
|
|
530
|
+
where_to_start = 0 # Reset to 0 since we cut the file
|
|
531
|
+
|
|
532
|
+
# Step 3.6: Ask for random shuffle option
|
|
533
|
+
if get_random_shuffle_choice():
|
|
534
|
+
print(f"\n🔀 正在随机打乱表达式顺序...")
|
|
535
|
+
expressions_with_settings = shuffle_json_file(json_path, expressions_with_settings)
|
|
536
|
+
|
|
537
|
+
# Step 3.7: Ask for multi-simulation mode
|
|
538
|
+
use_multi_sim = get_multi_simulation_choice()
|
|
539
|
+
alpha_count_per_slot = None
|
|
540
|
+
|
|
541
|
+
if use_multi_sim:
|
|
542
|
+
alpha_count_per_slot = get_alpha_count_per_slot()
|
|
543
|
+
# Convert to multi-alphas format
|
|
544
|
+
original_count = len(expressions_with_settings)
|
|
545
|
+
expressions_with_settings = wqb.to_multi_alphas(expressions_with_settings, alpha_count_per_slot)
|
|
546
|
+
print(f"\n✓ 已转换为多重回测(multi-simulatioin)格式")
|
|
547
|
+
print(f"📊 原始表达式数: {original_count}")
|
|
548
|
+
print(f"🎯 每槽alpha数: {alpha_count_per_slot}")
|
|
549
|
+
|
|
550
|
+
# Calculate how many expressions will be processed
|
|
551
|
+
print(f"🔄 使用 {concurrent_count} 个并发回测")
|
|
552
|
+
|
|
553
|
+
# Step 4: Write multi-simulation info to log if applicable
|
|
554
|
+
if use_multi_sim and alpha_count_per_slot and logger:
|
|
555
|
+
multi_sim_msg = (f"[MULTI-SIMULATION MODE] 以下是multi simulation的记录,"
|
|
556
|
+
f"你的设计是1个multi simulation中有{alpha_count_per_slot}个alpha,"
|
|
557
|
+
f"因此需将实际回测数乘以该乘数,才得到实际已完成的Alpha个数。")
|
|
558
|
+
logger.info("="*80)
|
|
559
|
+
logger.info(multi_sim_msg)
|
|
560
|
+
logger.info("="*80)
|
|
561
|
+
|
|
562
|
+
# Step 5: Start log monitoring in background
|
|
563
|
+
stop_log_monitor = threading.Event()
|
|
564
|
+
log_thread = threading.Thread(
|
|
565
|
+
target=monitor_log_file,
|
|
566
|
+
args=(logger, stop_log_monitor, use_multi_sim, alpha_count_per_slot),
|
|
567
|
+
daemon=True
|
|
568
|
+
)
|
|
569
|
+
log_thread.start()
|
|
570
|
+
|
|
571
|
+
# Step 6: Run simulations
|
|
572
|
+
print("\n" + "="*60)
|
|
573
|
+
print("运行回测")
|
|
574
|
+
print("="*60)
|
|
575
|
+
if use_multi_sim:
|
|
576
|
+
print("开始多重回测(multi-simulatioin)并发回测...")
|
|
577
|
+
else:
|
|
578
|
+
print("开始并发回测...")
|
|
579
|
+
|
|
580
|
+
try:
|
|
581
|
+
resps = await wqbs.concurrent_simulate(
|
|
582
|
+
expressions_with_settings,
|
|
583
|
+
concurrent_count,
|
|
584
|
+
log_gap=10
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
# Stop log monitoring
|
|
588
|
+
stop_log_monitor.set()
|
|
589
|
+
|
|
590
|
+
# Print results
|
|
591
|
+
print("\n" + "="*60)
|
|
592
|
+
print("回测结果")
|
|
593
|
+
print("="*60)
|
|
594
|
+
|
|
595
|
+
if use_multi_sim:
|
|
596
|
+
print(f"成功完成 {len(resps)} 个多重回测(multi-simulatioin)槽的回测")
|
|
597
|
+
else:
|
|
598
|
+
print(f"成功完成 {len(resps)} 个回测")
|
|
599
|
+
|
|
600
|
+
# print("\nAlpha IDs:")
|
|
601
|
+
# for i, resp in enumerate(resps):
|
|
602
|
+
# try:
|
|
603
|
+
# alpha_id = resp.json()['alpha']
|
|
604
|
+
# print(f" {i+1:4d}. {alpha_id}")
|
|
605
|
+
# except Exception as e:
|
|
606
|
+
# print(f" {i+1:4d}. 错误: {e}")
|
|
607
|
+
|
|
608
|
+
except KeyboardInterrupt:
|
|
609
|
+
print("\n\n⚠️ 回测被用户中断")
|
|
610
|
+
stop_log_monitor.set()
|
|
611
|
+
except Exception as e:
|
|
612
|
+
print(f"\n❌ 回测错误: {e}")
|
|
613
|
+
stop_log_monitor.set()
|
|
614
|
+
|
|
615
|
+
print("\n✅ 处理完成!")
|
|
616
|
+
|
|
617
|
+
if __name__ == '__main__':
|
|
618
|
+
asyncio.run(main())
|