diff --git a/AlphaGenerator.py b/AlphaGenerator.py new file mode 100644 index 0000000..b52a3c7 --- /dev/null +++ b/AlphaGenerator.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +import os +import json +import openai +import httpx +from datetime import datetime + + +def load_config(config_file="ai_config.json"): + try: + with open(config_file, 'r', encoding='utf-8') as f: + return json.load(f) + except FileNotFoundError: + print(f"创建配置文件: {config_file}") + with open(config_file, 'w', encoding='utf-8') as f: + json.dump({}, f, indent=4) + print("请在config.json中配置siliconflow的api信息") + return None + + +def create_prompt_file(): + if not os.path.exists("alpha_prompt.txt"): + with open("alpha_prompt.txt", 'w', encoding='utf-8') as f: + f.write("") + print("已创建alpha_prompt.txt,请填入提示词后重新运行") + return False + return True + + +def read_prompt(): + with open("alpha_prompt.txt", 'r', encoding='utf-8') as f: + prompt = f.read().strip() + if not prompt: + print("alpha_prompt.txt是空的,请填入提示词") + return None + return prompt + + +def create_result_folder(): + # 修改这里:创建 generated_alpha 文件夹 + folder_name = "generated_alpha" + if not os.path.exists(folder_name): + os.makedirs(folder_name) + return folder_name + + +def call_siliconflow(api_key, prompt, model, base_url): + try: + client = openai.OpenAI( + api_key=api_key, + base_url=base_url + ) + + response = client.chat.completions.create( + model=model, + messages=[{"role": "user", "content": prompt}] + ) + + return response.choices[0].message.content + + except openai.AuthenticationError: + print("API密钥错误") + except openai.RateLimitError: + print("调用频率限制") + except openai.APIError as e: + print(f"API错误: {e}") + except Exception as e: + print(f"其他错误: {e}") + return None + + +def save_result(result, folder): + timestamp = datetime.now().strftime("%Y%m%d%H%M%S") + filename = f"{timestamp}.txt" + filepath = os.path.join(folder, filename) + + with open(filepath, 'w', encoding='utf-8') as f: + f.write(result) + print(f"结果保存到: {filepath}") + + +def get_ai_config(config): + if not config: + return None + + service_name = list(config.keys())[0] + service_config = config[service_name] + + required_fields = ["api_keys", "model", "base_url"] + for field in required_fields: + if field not in service_config: + print(f"缺少配置字段: {field}") + return None + + return service_name, service_config + +def get_user_info(): + # 获取用户信息 + with open('config.json', 'r') as f: + config = json.load(f) + siliconflow = config['siliconflow'] + token = siliconflow['api_keys'] + + headers = {"Authorization": f"Bearer {token}"} + + url = "https://api.siliconflow.cn/v1/user/info" + + response = httpx.get(url, headers=headers) + + data = response.json()['data'] + balance = data['balance'] + print(f"余额: {balance}") + + +def main(): + get_user_info() + + config = load_config() + if not config: + return + + if not create_prompt_file(): + return + + prompt = read_prompt() + if not prompt: + return + + config_result = get_ai_config(config) + if not config_result: + return + + service_name, service_config = config_result + + print(f"使用服务: {service_name}") + print(f"使用模型: {service_config['model']}") + + folder = create_result_folder() + + print("正在调用AI...") + result = call_siliconflow( + service_config["api_keys"], + prompt, + service_config["model"], + service_config["base_url"] + ) + + if result: + print(f"AI回复: {result[:200]}...") + save_result(result, folder) + else: + print("AI调用失败") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/FactorSimulator.py b/FactorSimulator.py new file mode 100644 index 0000000..7179d33 --- /dev/null +++ b/FactorSimulator.py @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- +import os +import time +import json +import httpx +from httpx import BasicAuth + + +class AlphaSimulator: + def __init__(self, credentials_file='account.txt'): + self.credentials_file = credentials_file + self.client = None + self.brain_api_url = 'https://api.worldquantbrain.com' + + def load_credentials(self): + if not os.path.exists(self.credentials_file): + print("未找到 account.txt 文件") + with open(self.credentials_file, 'w') as f: + f.write("") + print("account.txt 文件已创建,请填写账号密码, 格式: ['username', 'password]") + exit(1) + + with open(self.credentials_file) as f: + credentials = eval(f.read()) + return credentials[0], credentials[1] + + def login(self): + username, password = self.load_credentials() + self.client = httpx.Client(auth=BasicAuth(username, password)) + + response = self.client.post(f'{self.brain_api_url}/authentication') + print(f"登录状态: {response.status_code}") + + if response.status_code == 201: + print("登录成功!") + return True + else: + print(f"登录失败: {response.json()}") + return False + + def load_alpha_list(self, file_path='alpha.txt'): + if not os.path.exists(file_path): + print(f"{file_path} 文件不存在") + with open(file_path, 'w', encoding='utf-8') as file: + file.write("") + print(f"已创建 {file_path} 文件, 请添加因子后重新运行, 一行一个因子") + return [] + + with open(file_path, 'r', encoding='utf-8') as file: + alpha_list = [line.strip() for line in file if line.strip()] + + return alpha_list + + def simulate_alpha(self, expression): + if self.client is None: + raise Exception("请先登录") + + settings = { + 'instrumentType': 'EQUITY', + 'region': 'USA', + 'universe': 'TOP3000', + 'delay': 1, + 'decay': 0, + 'neutralization': 'INDUSTRY', + 'truncation': 0.08, + 'pasteurization': 'ON', + 'unitHandling': 'VERIFY', + 'nanHandling': 'OFF', + 'language': 'FASTEXPR', + 'visualization': False, + } + + simulation_data = { + 'type': 'REGULAR', + 'settings': settings, + 'regular': expression + } + + sim_resp = self.client.post(f'{self.brain_api_url}/simulations', json=simulation_data) + print(f"模拟提交状态: {sim_resp.status_code}") + + sim_progress_url = sim_resp.headers['location'] + + while True: + sim_progress_resp = self.client.get(sim_progress_url) + retry_after_sec = float(sim_progress_resp.headers.get("Retry-After", 0)) + + if retry_after_sec == 0: + break + + if sim_progress_resp.json(): + result = sim_progress_resp.json() + progress = result.get('progress', 0) + print(f"模拟进度: {float(progress) * 100}%") + + print(f"等待 {retry_after_sec} 秒...") + time.sleep(retry_after_sec) + + if sim_progress_resp.json().get("status") == "ERROR": + result = sim_progress_resp.json().get("message", "未知错误") + print(f"因子模拟失败: {result}") + return {"status": "error", "message": result} + + alpha_id = sim_progress_resp.json().get("alpha") + print(f"生成的Alpha ID: {alpha_id}") + + return {"status": "success", "alpha_id": alpha_id} + + def run_batch_simulation(self, alpha_list, batch_size=3): + success_results = [] + fail_results = [] + + for i in range(0, len(alpha_list), batch_size): + batch = alpha_list[i:i + batch_size] + print(f"\n开始处理第 {i // batch_size + 1} 批因子,共 {len(batch)} 个") + + for expression in batch: + print(f"\n模拟因子: {expression}") + start_time = time.time() + + try: + result = self.simulate_alpha(expression) + end_time = time.time() + time_consuming = end_time - start_time + + result_data = { + "expression": expression, + "time_consuming": round(time_consuming, 2), + "status": result["status"], + "timestamp": time.strftime("%Y-%m-%d %H:%M:%S") + } + + if result["status"] == "success": + result_data["alpha_id"] = result["alpha_id"] + success_results.append(result_data) + print(f"✅ 模拟成功 - Alpha ID: {result['alpha_id']} - 耗时: {time_consuming:.2f}秒") + else: + result_data["message"] = result.get("message", "") + fail_results.append(result_data) + print(f"❌ 模拟失败 - {result.get('message', '未知错误')}") + + except Exception as e: + end_time = time.time() + time_consuming = end_time - start_time + error_result = { + "expression": expression, + "time_consuming": round(time_consuming, 2), + "status": "error", + "message": str(e), + "timestamp": time.strftime("%Y-%m-%d %H:%M:%S") + } + fail_results.append(error_result) + print(f"❌ 模拟异常 - {str(e)}") + + print(f"第 {i // batch_size + 1} 批处理完成") + + self._save_results(success_results, fail_results) + return success_results, fail_results + + def _save_results(self, success_results, fail_results): + base_dir = 'simulator_result' + success_dir = os.path.join(base_dir, 'success') + fail_dir = os.path.join(base_dir, 'fail') + + os.makedirs(success_dir, exist_ok=True) + os.makedirs(fail_dir, exist_ok=True) + + timestamp = str(int(time.time())) + + if success_results: + success_file = os.path.join(success_dir, f"success_results_{timestamp}.json") + with open(success_file, 'w', encoding='utf-8') as f: + json.dump(success_results, f, ensure_ascii=False, indent=2) + print(f"成功结果已保存到 {success_file}") + + if fail_results: + fail_file = os.path.join(fail_dir, f"fail_results_{timestamp}.json") + with open(fail_file, 'w', encoding='utf-8') as f: + json.dump(fail_results, f, ensure_ascii=False, indent=2) + print(f"失败结果已保存到 {fail_file}") + + print(f"\n总计: 成功 {len(success_results)} 个, 失败 {len(fail_results)} 个") + + +def main(): + simulator = AlphaSimulator() + + if not simulator.login(): + return + + alpha_list = simulator.load_alpha_list('alpha.txt') + if not alpha_list: + print("未找到有效的因子表达式,请检查 alpha.txt 文件") + return + + print(f"共加载 {len(alpha_list)} 个因子表达式") + + simulator.run_batch_simulation(alpha_list, batch_size=3) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/FieldDownloader.py b/FieldDownloader.py new file mode 100644 index 0000000..1ba8597 --- /dev/null +++ b/FieldDownloader.py @@ -0,0 +1,195 @@ +import os +import json +import random +import time +import httpx +from httpx import BasicAuth + + +class BrainLogin: + def __init__(self, credentials_file='account.txt'): + self.credentials_file = credentials_file + self.client = None + self.brain_api_url = 'https://api.worldquantbrain.com' + + def load_credentials(self): + if not os.path.exists(self.credentials_file): + print("未找到 account.txt 文件") + with open(self.credentials_file, 'w') as f: + f.write("") + print("account.txt 文件已创建,请填写账号密码, 格式: ['username', 'password']") + exit(1) + + with open(self.credentials_file) as f: + credentials = eval(f.read()) + return credentials[0], credentials[1] + + def login(self): + try: + username, password = self.load_credentials() + self.client = httpx.Client(auth=BasicAuth(username, password)) + + response = self.client.post(f'{self.brain_api_url}/authentication') + print(f"登录状态: {response.status_code}") + + if response.status_code in [200, 201]: + print("登录成功!") + print(f"账户信息: {response.json()}") + return self.client + else: + print(f"登录失败: {response.json()}") + return None + + except Exception as e: + print(f"登录过程中出现错误: {e}") + return None + + def get_client(self): + return self.client + + +class DataSetDownloader: + def __init__(self, client): + self.client = client + self.base_api_url = 'https://api.worldquantbrain.com' + + def debug_detailed_response(self, endpoint, data_set_id, offset, limit=20): + print(f"\n=== 调试请求: {endpoint} ===") + url = f"{self.base_api_url}/{endpoint}" + params = { + 'dataset.id': data_set_id, + 'delay': 1, + 'instrumentType': 'EQUITY', + 'limit': limit, + 'offset': offset, + 'region': 'USA', + 'universe': 'TOP3000' + } + + response = self.client.get(url, params=params) + + if response.status_code == 200: + data = response.json() + print(f"count: {data.get('count')}") + print(f"results 长度: {len(data.get('results', []))}") + print(f"响应键: {list(data.keys())}") + + def process_data(self, raw_data): + processed_data = [] + + for item in raw_data: + processed_item = { + 'id': item.get('id', ''), + 'description': item.get('description', ''), + 'dataset_id': item.get('dataset', {}).get('id', ''), + 'dataset_name': item.get('dataset', {}).get('name', ''), + 'category_id': item.get('category', {}).get('id', ''), + 'category_name': item.get('category', {}).get('name', ''), + 'region': item.get('region', ''), + 'delay': item.get('delay', ''), + 'universe': item.get('universe', ''), + 'type': item.get('type', '') + } + processed_data.append(processed_item) + + return processed_data + + def download_data_set(self, endpoint, data_set_id): + output_dir = 'reference_fields' + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + self.debug_detailed_response(endpoint, data_set_id, offset=0, limit=20) + + url = f"{self.base_api_url}/{endpoint}" + params = { + 'dataset.id': data_set_id, + 'delay': 1, + 'instrumentType': 'EQUITY', + 'limit': 1, + 'offset': 0, + 'region': 'USA', + 'universe': 'TOP3000' + } + + response = self.client.get(url, params=params) + data = response.json() + total_count = data.get('count', 0) + + print(f"📊 数据集总数: {total_count}") + + if total_count == 0: + print("❌ 没有找到数据") + return + + limit = 50 + all_data = [] + + print("🚀 开始下载数据...") + for offset in range(0, total_count, limit): + sleep_time = random.uniform(1.0, 1.5) + time.sleep(sleep_time) + + params = { + 'dataset.id': data_set_id, + 'delay': 1, + 'instrumentType': 'EQUITY', + 'limit': limit, + 'offset': offset, + 'region': 'USA', + 'universe': 'TOP3000' + } + + print(f"📥 下载进度: {offset}/{total_count} ({offset / total_count * 100:.1f}%)") + + try: + response = self.client.get(url, params=params) + + if response.status_code == 200: + data = response.json() + results = data.get('results', []) + + print(f"✅ 本页获取到 {len(results)} 条记录") + all_data.extend(results) + print(f"✅ 累计获取 {len(all_data)} 条记录") + + if len(results) < limit: + print("🎯 到达数据末尾") + break + else: + print(f"❌ 请求失败: {response.status_code}") + break + + except Exception as e: + print(f"❌ 下载过程中出错: {e}") + break + + print("🔄 处理数据中...") + processed_data = self.process_data(all_data) + + output_file = os.path.join(output_dir, f"{data_set_id}_{endpoint}.json") + with open(output_file, 'w', encoding='utf-8') as f: + json.dump(processed_data, f, ensure_ascii=False, indent=2) + + print(f"💾 处理后的数据已保存到: {output_file}") + print(f"🎉 总共处理了 {len(processed_data)} 条记录") + + if processed_data: + print("\n📋 处理后数据示例:") + print(json.dumps(processed_data[0], indent=2, ensure_ascii=False)) + + +if __name__ == "__main__": + brain_login = BrainLogin() + client = brain_login.login() + + if client: + downloader = DataSetDownloader(client) + + endpoint_list = ['data-sets', 'data-fields'] + endpoint = endpoint_list[1] + data_set_id = 'news18' + + downloader.download_data_set(endpoint, data_set_id) + else: + print("❌ 登录失败,无法下载数据") \ No newline at end of file diff --git a/wqb-filter-alpha/account.txt b/account.txt similarity index 100% rename from wqb-filter-alpha/account.txt rename to account.txt diff --git a/ai_config.json b/ai_config.json new file mode 100644 index 0000000..ba31892 --- /dev/null +++ b/ai_config.json @@ -0,0 +1,7 @@ +{ + "siliconflow": { + "base_url": "https://api.siliconflow.cn/v1", + "api_keys": "sk-pvdiisdowmuwkrpnxsrlhxaovicqibmlljwrwwvbbdjaitdl", + "model": "Qwen/Qwen3-VL-235B-A22B-Instruct" + } +} \ No newline at end of file diff --git a/alpha.txt b/alpha.txt new file mode 100644 index 0000000..6224201 --- /dev/null +++ b/alpha.txt @@ -0,0 +1 @@ +group_mean(ts_rank(volume, 252), industry) \ No newline at end of file diff --git a/alpha_prompt.txt b/alpha_prompt.txt new file mode 100644 index 0000000..11e72c8 --- /dev/null +++ b/alpha_prompt.txt @@ -0,0 +1,37 @@ +【重要平台约束】 +平台:WorldQuant WebSim +可用函数:ts_*(时间序列), group_*(横截面), 基础数学运算 +可用字段:open, high, low, close, volume, vwap, sector, industry, country, market_cap +禁用函数:pandas, numpy, 自定义Python函数,机器学习库 +输出格式:严格一行WebSim表达式,使用WQ平台函数 +表达式要求:必须能直接在WebSim中运行 + +我正在WorldQuant研究行业轮动策略,请设计行业选择因子: + +**策略背景**: +- 目标:在不同经济周期中选择强势行业 +- 数据:使用sector, industry分类字段 +- 频率:月度调仓 +- 风险:控制行业集中度 + +**需要5个行业因子**: +1. 行业动量因子(相对强度) +2. 行业估值修复因子(均值回归) +3. 行业资金流向因子(量价结合) +4. 行业波动率特征因子(风险调整) +5. 行业间相对强度因子(横截面) + +**具体要求**: +- 必须使用group函数处理行业分组 +- 每个因子包含清晰的行业轮动逻辑 +- 考虑行业特性的持久性 +- 提供经济周期适应的解释 + +**输出格式**(一行一个, 不要输出多余的东西): +[表达式] +[表达式] +[表达式] +... + +请提供具体的WQ表达式。 +重申:请确保所有表达式都使用WorldQuant WebSim平台函数,不要使用pandas、numpy或其他Python库函数。输出必须是一行有效的WQ表达式。 \ No newline at end of file diff --git a/wq101alphas/alpha101_code/01-alpha因子编写 b/reference_data/wq101alphas/alpha101_code/01-alpha因子编写 similarity index 100% rename from wq101alphas/alpha101_code/01-alpha因子编写 rename to reference_data/wq101alphas/alpha101_code/01-alpha因子编写 diff --git a/wq101alphas/alpha101_code/02-基于万矿计算因子数据 b/reference_data/wq101alphas/alpha101_code/02-基于万矿计算因子数据 similarity index 100% rename from wq101alphas/alpha101_code/02-基于万矿计算因子数据 rename to reference_data/wq101alphas/alpha101_code/02-基于万矿计算因子数据 diff --git a/wq101alphas/alpha101_code/03-单因子IC测试 b/reference_data/wq101alphas/alpha101_code/03-单因子IC测试 similarity index 100% rename from wq101alphas/alpha101_code/03-单因子IC测试 rename to reference_data/wq101alphas/alpha101_code/03-单因子IC测试 diff --git a/wq101alphas/alpha101_code/04-单因子分层测试 b/reference_data/wq101alphas/alpha101_code/04-单因子分层测试 similarity index 100% rename from wq101alphas/alpha101_code/04-单因子分层测试 rename to reference_data/wq101alphas/alpha101_code/04-单因子分层测试 diff --git a/wq101alphas/alpha101_code/05-回测相关处理函数 b/reference_data/wq101alphas/alpha101_code/05-回测相关处理函数 similarity index 100% rename from wq101alphas/alpha101_code/05-回测相关处理函数 rename to reference_data/wq101alphas/alpha101_code/05-回测相关处理函数 diff --git a/wq101alphas/alpha101_code/06-有效因子回测 b/reference_data/wq101alphas/alpha101_code/06-有效因子回测 similarity index 100% rename from wq101alphas/alpha101_code/06-有效因子回测 rename to reference_data/wq101alphas/alpha101_code/06-有效因子回测 diff --git a/wq101alphas/alpha101_code/README.md b/reference_data/wq101alphas/alpha101_code/README.md similarity index 100% rename from wq101alphas/alpha101_code/README.md rename to reference_data/wq101alphas/alpha101_code/README.md diff --git a/wq101alphas/wq101alpha.dos b/reference_data/wq101alphas/wq101alpha.dos similarity index 100% rename from wq101alphas/wq101alpha.dos rename to reference_data/wq101alphas/wq101alpha.dos diff --git a/wq101alphas/wq101alpha.json b/reference_data/wq101alphas/wq101alpha.json similarity index 100% rename from wq101alphas/wq101alpha.json rename to reference_data/wq101alphas/wq101alpha.json diff --git a/wq101alphas/wq101alpha2json.py b/reference_data/wq101alphas/wq101alpha2json.py similarity index 100% rename from wq101alphas/wq101alpha2json.py rename to reference_data/wq101alphas/wq101alpha2json.py diff --git a/reference_fields/news18_data-fields.json b/reference_fields/news18_data-fields.json new file mode 100644 index 0000000..9f0876e --- /dev/null +++ b/reference_fields/news18_data-fields.json @@ -0,0 +1,902 @@ +[ + { + "id": "nws18_acb", + "description": "News sentiment specializing in corporate action announcements", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_bam", + "description": "News sentiment specializing in mergers and acquisitions", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_bee", + "description": "News sentiment specializing in growth of earnings", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_ber", + "description": "News sentiment specializing in earnings result", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_event_relevance", + "description": "Relevance of the event to the story", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_event_similarity_days", + "description": "Days since a similar event was detected", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_ghc_lna", + "description": "Change in analyst recommendation", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_nip", + "description": "Degree of impact of the news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_qcm", + "description": "News sentiment of relevant news with high confidence", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_qep", + "description": "News sentiment based on positive and negative words on global equity", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_qmb", + "description": "News sentiment specializing in editorials on global markets", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_relevance", + "description": "Relevance of news to the company", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_ssc", + "description": "Sentiment of the news calculated using multiple techniques", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "nws18_sse", + "description": "Sentiment of phrases impacting the company", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "VECTOR" + }, + { + "id": "rp_css_assets", + "description": "Composite sentiment score of assets news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_business", + "description": "Composite sentiment score of business-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_credit", + "description": "Composite sentiment score of credit news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_credit_ratings", + "description": "Composite sentiment score of credit ratings news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_dividends", + "description": "Composite sentiment score of dividends news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_earnings", + "description": "Composite sentiment score of earnings news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_equity", + "description": "Composite sentiment score of equity action news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_insider", + "description": "Composite sentiment score of insider trading news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_inverstor", + "description": "Composite sentiment score of investor relations news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_labor", + "description": "Composite sentiment score of labor issues news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_legal", + "description": "Composite sentiment score of legal news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_marketing", + "description": "Composite sentiment score of marketing news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_mna", + "description": "Composite sentiment score of mergers and acquisitions-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_partner", + "description": "Composite sentiment score of partnership news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_price", + "description": "Composite sentiment score of stock price news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_product", + "description": "Composite sentiment score of product and service-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_ptg", + "description": "Composite sentiment score of price target news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_ratings", + "description": "Composite sentiment score of analyst ratings-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_revenue", + "description": "Composite sentiment score of revenue news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_society", + "description": "Composite sentiment score of society-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_css_technical", + "description": "Composite sentiment score based on technical analysis", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_assets", + "description": "Event sentiment score of assets news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_business", + "description": "Event sentiment score of business-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_credit", + "description": "Event sentiment score of credit news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_credit_ratings", + "description": "Event sentiment score of credit ratings news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_dividends", + "description": "Event sentiment score of dividends news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_earnings", + "description": "Event sentiment score of earnings news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_equity", + "description": "Event sentiment score of equity action news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_insider", + "description": "Event sentiment score of insider trading news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_labor", + "description": "Event sentiment score of labor issues news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_legal", + "description": "Event sentiment score of legal news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_mna", + "description": "Event sentiment score of mergers and acquisitions-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_partner", + "description": "Event sentiment score of partnership news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_price", + "description": "Event sentiment score of stock price news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_product", + "description": "Event sentiment score of product and service-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_ptg", + "description": "Event sentiment score of price target news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_ratings", + "description": "Event sentiment score of analyst ratings-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_revenue", + "description": "Event sentiment score of revenue news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_society", + "description": "Event sentiment score of society-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_ess_technical", + "description": "Event sentiment score based on technical analysis", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_assets", + "description": "News impact projection of assets news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_business", + "description": "News impact projection of business-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_credit", + "description": "News impact projection of credit news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_credit_ratings", + "description": "News impact projection of credit ratings news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_dividends", + "description": "News impact projection of dividends news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_earnings", + "description": "News impact projection of earnings news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_equity", + "description": "News impact projection of equity action news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_insider", + "description": "News impact projection of insider trading news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_inverstor", + "description": "News impact projection of investor relations news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_labor", + "description": "News impact projection of labor issues news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_legal", + "description": "News impact projection of legal news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_marketing", + "description": "News impact projection of marketing news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_mna", + "description": "News impact projection of mergers and acquisitions-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_partner", + "description": "News impact projection of partnership news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_price", + "description": "News impact projection of stock price news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_product", + "description": "News impact projection of product and service-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_ptg", + "description": "News impact projection of price target news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_ratings", + "description": "News impact projection of analyst ratings-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_revenue", + "description": "News impact projection of revenue news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_society", + "description": "News impact projection of society-related news", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + }, + { + "id": "rp_nip_technical", + "description": "News impact projection based on technical analysis", + "dataset_id": "news18", + "dataset_name": "Ravenpack News Data", + "category_id": "news", + "category_name": "News", + "region": "USA", + "delay": 1, + "universe": "TOP3000", + "type": "MATRIX" + } +] \ No newline at end of file diff --git a/simulator_result/fail/fail_results_1764034041.json b/simulator_result/fail/fail_results_1764034041.json new file mode 100644 index 0000000..a3d2fd3 --- /dev/null +++ b/simulator_result/fail/fail_results_1764034041.json @@ -0,0 +1,9 @@ +[ + { + "expression": "group_mean(ts_rank(volume, 252), industry)", + "time_consuming": 6.65, + "status": "error", + "timestamp": "2025-11-25 09:27:21", + "message": "Invalid number of inputs : 2, should be exactly 3 input(s)" + } +] \ No newline at end of file diff --git a/demo_generating_factor/test001.py b/test/demo_generating_factor/test001.py similarity index 100% rename from demo_generating_factor/test001.py rename to test/demo_generating_factor/test001.py diff --git a/demo_yfinance/demo.py b/test/demo_yfinance/demo.py similarity index 100% rename from demo_yfinance/demo.py rename to test/demo_yfinance/demo.py diff --git a/wqb-demo/alphas.json b/test/wqb-demo/alphas.json similarity index 100% rename from wqb-demo/alphas.json rename to test/wqb-demo/alphas.json diff --git a/wqb-demo/brain_credentials.txt b/test/wqb-demo/brain_credentials.txt similarity index 100% rename from wqb-demo/brain_credentials.txt rename to test/wqb-demo/brain_credentials.txt diff --git a/wqb-demo/main.py b/test/wqb-demo/main.py similarity index 100% rename from wqb-demo/main.py rename to test/wqb-demo/main.py diff --git a/wqb-demo/main_simple.py b/test/wqb-demo/main_simple.py similarity index 100% rename from wqb-demo/main_simple.py rename to test/wqb-demo/main_simple.py diff --git a/wqb-demo/simulation_results.json b/test/wqb-demo/simulation_results.json similarity index 100% rename from wqb-demo/simulation_results.json rename to test/wqb-demo/simulation_results.json diff --git a/wqb-simulate/account.txt b/test/wqb-filter-alpha/account.txt similarity index 100% rename from wqb-simulate/account.txt rename to test/wqb-filter-alpha/account.txt diff --git a/wqb-filter-alpha/filter-alpha.py b/test/wqb-filter-alpha/filter-alpha.py similarity index 100% rename from wqb-filter-alpha/filter-alpha.py rename to test/wqb-filter-alpha/filter-alpha.py diff --git a/wqb-login/brain_credentials.txt b/test/wqb-login/account.txt similarity index 100% rename from wqb-login/brain_credentials.txt rename to test/wqb-login/account.txt diff --git a/wqb-login/login.py b/test/wqb-login/login.py similarity index 73% rename from wqb-login/login.py rename to test/wqb-login/login.py index b30249a..9532230 100644 --- a/wqb-login/login.py +++ b/test/wqb-login/login.py @@ -1,9 +1,16 @@ import httpx from httpx import BasicAuth +import os -def login(credentials_file='brain_credentials.txt'): +def login(credentials_file='account.txt'): """登录WorldQuant Brain API""" # 读取本地账号密码 + if not os.path.exists(credentials_file): + print("未找到 account.txt 文件") + with open(credentials_file, 'w') as f: f.write("") + print("account.txt 文件已创建,请填写账号密码, 格式: ['username', 'password]") + exit(1) + with open(credentials_file) as f: credentials = eval(f.read()) username, password = credentials[0], credentials[1] diff --git a/test/wqb-simulate/account.txt b/test/wqb-simulate/account.txt new file mode 100644 index 0000000..5cfaa62 --- /dev/null +++ b/test/wqb-simulate/account.txt @@ -0,0 +1 @@ +['jack0210_@hotmail.com', '!QAZ2wsx+0913'] \ No newline at end of file diff --git a/wqb-simulate/alpha.txt b/test/wqb-simulate/alpha.txt similarity index 100% rename from wqb-simulate/alpha.txt rename to test/wqb-simulate/alpha.txt diff --git a/wqb-simulate/simulate.py b/test/wqb-simulate/simulate.py similarity index 100% rename from wqb-simulate/simulate.py rename to test/wqb-simulate/simulate.py diff --git a/wqb-test/main.py b/test/wqb-test/main.py similarity index 100% rename from wqb-test/main.py rename to test/wqb-test/main.py