main
jack 2 months ago
parent 0b84cb8222
commit d4e55e9aca
  1. 25
      Readme.md
  2. 13
      __init__.py
  3. 1
      alpha.txt
  4. 8
      config/__init__.py
  5. 70
      config/settings.py
  6. 9
      core/__init__.py
  7. 158
      core/api_client.py
  8. 176
      core/database.py
  9. 62
      core/models.py
  10. 126
      core/simulator.py
  11. 46
      main.py
  12. 8
      managers/__init__.py
  13. 232
      managers/simulation_manager.py
  14. 0
      models/__init__.py
  15. 32
      models/entities.py
  16. 168
      reference/yearly-stats.json
  17. 137
      reference/指标.json
  18. 22
      reference/进度.json
  19. 714
      requirements.txt
  20. 289
      result/simulation_results-1763109446.json
  21. 524
      result/simulation_results-1763110929.json
  22. 82
      result/simulation_results-1763112962.json
  23. 12
      result/simulation_results-1763113286.json
  24. 0
      services/__init__.py
  25. 60
      services/alpha_service.py
  26. 57
      services/auth_service.py
  27. 27
      services/notification_service.py
  28. 4
      success.txt
  29. 9
      utils/__init__.py
  30. 84
      utils/file_utils.py
  31. 23
      utils/helpers.py
  32. 9
      utils/time_utils.py

@ -1,25 +0,0 @@
### 依赖
pip install httpx
### 目录结构
```text
FactorSimulator/
├── __init__.py # 包初始化文件,定义包级别的导入和元数据
├── main.py # 程序主入口,负责启动批量模拟流程
├── core/ # 核心业务逻辑模块
│ ├── __init__.py # 核心模块初始化,定义模块级别的导入
│ ├── api_client.py # WorldQuant Brain API客户端封装,处理HTTP请求和认证
│ └── models.py # 数据模型定义,使用dataclass定义各种指标和结果的数据结构
├── managers/ # 管理器模块,负责业务流程协调
│ ├── __init__.py # 管理器模块初始化
│ └── simulation_manager.py # 模拟管理器,负责批量模拟的调度、线程池管理和结果汇总
├── utils/ # 工具函数模块
│ ├── __init__.py # 工具模块初始化
│ ├── file_utils.py # 文件操作工具,处理因子列表加载和结果保存
│ └── time_utils.py # 时间格式化工具,将秒数转换为可读格式
└── config/ # 配置模块
├── __init__.py # 配置模块初始化
└── settings.py # 模拟参数配置,定义默认的模拟设置常量
```

@ -1,13 +0,0 @@
# -*- coding: utf-8 -*-
"""
WorldQuant Brain 因子模拟器
用于批量模拟Alpha因子的工具
"""
__version__ = "0.0.1"
__author__ = "Jack"
from .core.api_client import WorldQuantBrainSimulate
from .managers.simulation_manager import AlphaSimulationManager
__all__ = ['WorldQuantBrainSimulate', 'AlphaSimulationManager']

@ -1 +0,0 @@
ts_delta(ts_mean(close, 5), 10) / ts_std(close, 20) * (ts_mean(close, 20) / ts_mean(close, 100) > 1.02)

@ -1,8 +0,0 @@
# -*- coding: utf-8 -*-
"""
配置模块 - 包含配置常量
"""
from .settings import DEFAULT_SIMULATION_SETTINGS
__all__ = ['DEFAULT_SIMULATION_SETTINGS']

@ -1,19 +1,53 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """配置文件"""
模拟配置常量
""" import os
from typing import Dict, Any
DEFAULT_SIMULATION_SETTINGS = {
'instrumentType': 'EQUITY',
'region': 'USA', class Settings:
'universe': 'TOP3000', """应用配置"""
'delay': 1,
'decay': 0, # 数据库配置
'neutralization': 'INDUSTRY', DATABASE_CONFIG = {
'truncation': 0.08, "host": "localhost",
'pasteurization': 'ON', "port": "5432",
'unitHandling': 'VERIFY', "user": "jack",
'nanHandling': 'OFF', "password": "aaaAAA111",
'language': 'FASTEXPR', "database": "alpha"
'visualization': False, }
}
# API配置
BRAIN_API_URL = "https://api.worldquantbrain.com"
# 模拟配置
SIMULATION_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,
}
# 批处理配置
BATCH_SIZE = 3
CHECK_INTERVAL = 300 # 5分钟
TOKEN_REFRESH_THRESHOLD = 1800 # 30分钟
# 通知配置
GOTIFY_URL = "https://gotify.erhe.top/message?token=AvKJCJwQKU6yLP8"
@property
def credentials_file(self) -> str:
"""获取凭证文件路径"""
return os.path.join(os.path.dirname(os.path.dirname(__file__)), 'account.txt')
settings = Settings()

@ -1,9 +0,0 @@
# -*- coding: utf-8 -*-
"""
核心模块 - 包含API客户端和数据模型
"""
from .api_client import WorldQuantBrainSimulate
from .models import AlphaMetrics, SimulationResult
__all__ = ['WorldQuantBrainSimulate', 'AlphaMetrics', 'SimulationResult']

@ -1,158 +0,0 @@
# -*- coding: utf-8 -*-
import os.path
import httpx
import time
from httpx import BasicAuth
from typing import Dict, Any, Optional, Tuple
class WorldQuantBrainSimulate:
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) -> Tuple[str, str]:
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) -> bool:
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("登录成功!")
print(f"账户信息: {response.json()}")
return True
else:
print(f"登录失败: {response.json()}")
return False
"""模拟Alpha因子"""
def simulate_alpha(self, expression: str, settings: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
if self.client is None:
raise Exception("请先登录")
default_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,
}
if settings:
default_settings.update(settings)
simulation_data = {
'type': 'REGULAR',
'settings': default_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']
print(f"进度URL: {sim_progress_url}")
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['progress']
if progress:
print(f"模拟进度: {float(progress)*100}%")
print(f"等待 {retry_after_sec} 秒...")
time.sleep(retry_after_sec)
# 如果因子模拟不通过, 获取一下失败信息
if sim_progress_resp.json()["status"] == "ERROR":
result = sim_progress_resp.json()["message"]
print(f"因子模拟失败: {result}")
# 返回一个特殊标识,表示模拟失败
return {"status": "error", "message": result}
alpha_id = sim_progress_resp.json()["alpha"]
print(f"生成的Alpha ID: {alpha_id}")
# 获取详细的性能指标
metrics = self.get_alpha_metrics(alpha_id)
return {"status": "success", "alpha_id": alpha_id, "metrics": metrics}
"""获取Alpha因子的详细指标"""
def get_alpha_metrics(self, alpha_id: str) -> Dict[str, Any]:
if self.client is None:
raise Exception("请先登录")
try:
# 获取Alpha的基本信息和指标
alpha_url = f'{self.brain_api_url}/alphas/{alpha_id}'
alpha_resp = self.client.get(alpha_url)
if alpha_resp.status_code in [200, 201]:
alpha_data = alpha_resp.json()
# 以后可能需要获取其他参数
if alpha_data.get('metrics'):
alpha_data = alpha_data.get('metrics')
return alpha_data or {}
else:
print(f"获取Alpha指标失败: {alpha_resp.status_code}")
# 返回一个空的字典结构
return {
"train": {},
"is": {},
"test": {},
"grade": None,
"stage": None,
"status": None,
"dateCreated": None,
"id": alpha_id
}
except Exception as e:
print(f"获取指标时出错: {str(e)}")
# 返回一个空的字典结构
return {
"train": {},
"is": {},
"test": {},
"grade": None,
"stage": None,
"status": None,
"dateCreated": None,
"id": alpha_id
}
def close(self):
"""关闭连接"""
if self.client:
self.client.close()

@ -0,0 +1,176 @@
# -*- coding: utf-8 -*-
"""数据库管理层"""
import psycopg2
from typing import List, Optional
from config.settings import settings
from models.entities import SimulationResult, AlphaExpression
class DatabaseManager:
"""数据库管理类"""
def __init__(self):
self.connection = None
self.init_database()
def create_database(self) -> None:
"""创建数据库(如果不存在)"""
try:
# 先连接到默认的postgres数据库来创建alpha数据库
conn = psycopg2.connect(
host=settings.DATABASE_CONFIG["host"],
port=settings.DATABASE_CONFIG["port"],
database="postgres",
user=settings.DATABASE_CONFIG["user"],
password=settings.DATABASE_CONFIG["password"]
)
conn.autocommit = True
cursor = conn.cursor()
# 检查数据库是否存在
cursor.execute("SELECT 1 FROM pg_catalog.pg_database WHERE datname = %s",
(settings.DATABASE_CONFIG["database"],))
exists = cursor.fetchone()
if not exists:
cursor.execute(f"CREATE DATABASE {settings.DATABASE_CONFIG['database']}")
print(f"数据库 {settings.DATABASE_CONFIG['database']} 创建成功")
else:
print(f"数据库 {settings.DATABASE_CONFIG['database']} 已存在")
cursor.close()
conn.close()
except Exception as e:
print(f"创建数据库时出错: {e}")
raise
def get_connection(self) -> psycopg2.extensions.connection:
"""获取数据库连接"""
if self.connection is None or self.connection.closed:
self.connection = psycopg2.connect(
host=settings.DATABASE_CONFIG["host"],
port=settings.DATABASE_CONFIG["port"],
database=settings.DATABASE_CONFIG["database"],
user=settings.DATABASE_CONFIG["user"],
password=settings.DATABASE_CONFIG["password"]
)
return self.connection
def init_database(self) -> None:
"""初始化数据库和表结构"""
# 先创建数据库
self.create_database()
# 然后连接到此数据库创建表
conn = self.get_connection()
cursor = conn.cursor()
# 创建 alpha_prepare 表
cursor.execute('''
CREATE TABLE IF NOT EXISTS alpha_prepare
(
id
SERIAL
PRIMARY
KEY,
alpha
TEXT
NOT
NULL
UNIQUE,
unused
BOOLEAN
NOT
NULL
DEFAULT
TRUE,
created_time
TIMESTAMP
DEFAULT
CURRENT_TIMESTAMP
)
''')
# 创建 simulation 表
cursor.execute('''
CREATE TABLE IF NOT EXISTS simulation
(
id
SERIAL
PRIMARY
KEY,
expression
TEXT
NOT
NULL,
time_consuming
REAL
NOT
NULL,
status
TEXT
NOT
NULL,
timestamp
TEXT
NOT
NULL,
alpha_id
TEXT,
message
TEXT,
created_time
TIMESTAMP
DEFAULT
CURRENT_TIMESTAMP
)
''')
conn.commit()
print(f"数据库 {settings.DATABASE_CONFIG['database']} 表结构初始化完成")
def get_unused_alpha(self) -> List[str]:
"""获取所有未使用的alpha表达式"""
conn = self.get_connection()
cursor = conn.cursor()
cursor.execute("SELECT alpha FROM alpha_prepare WHERE unused = TRUE")
results = cursor.fetchall()
alpha_list = [result[0] for result in results]
return alpha_list
def mark_alpha_used(self, alpha: str) -> None:
"""将alpha标记为已使用"""
conn = self.get_connection()
cursor = conn.cursor()
cursor.execute("UPDATE alpha_prepare SET unused = FALSE WHERE alpha = %s", (alpha,))
conn.commit()
def insert_simulation_result(self, result: SimulationResult) -> None:
"""插入模拟结果到simulation表"""
conn = self.get_connection()
cursor = conn.cursor()
cursor.execute('''
INSERT INTO simulation
(expression, time_consuming, status, timestamp, alpha_id, message)
VALUES (%s, %s, %s, %s, %s, %s)
''', (
result.expression,
result.time_consuming,
result.status,
result.timestamp,
result.alpha_id,
result.message or ""
))
conn.commit()
def close_connection(self) -> None:
"""关闭数据库连接"""
if self.connection and not self.connection.closed:
self.connection.close()

@ -1,62 +0,0 @@
# -*- coding: utf-8 -*-
from dataclasses import dataclass
from typing import Dict, Any, Optional
@dataclass
class TrainMetrics:
"""训练集指标"""
sharpe_ratio: Optional[float] = None
annual_return: Optional[float] = None
max_drawdown: Optional[float] = None
turnover: Optional[float] = None
fitness: Optional[float] = None
pnl: Optional[float] = None
book_size: Optional[float] = None
long_count: Optional[float] = None
short_count: Optional[float] = None
margin: Optional[float] = None
@dataclass
class TestMetrics:
"""测试集指标"""
sharpe_ratio: Optional[float] = None
annual_return: Optional[float] = None
max_drawdown: Optional[float] = None
turnover: Optional[float] = None
fitness: Optional[float] = None
pnl: Optional[float] = None
@dataclass
class AlphaInfo:
"""Alpha基本信息"""
grade: Optional[str] = None
stage: Optional[str] = None
status: Optional[str] = None
date_created: Optional[str] = None
checks: Optional[Dict[str, Any]] = None
@dataclass
class AlphaMetrics:
"""Alpha因子完整指标"""
train_metrics: TrainMetrics
is_metrics: TestMetrics
test_metrics: TestMetrics
alpha_info: AlphaInfo
alpha_id: Optional[str] = None
@dataclass
class SimulationResult:
"""模拟结果"""
expression: str
time_consuming: float
formatted_time: str
alpha_id: str
status: str
description: str
simulation_timestamp: str
metrics: Optional[Dict[str, Any]] = None

@ -0,0 +1,126 @@
# -*- coding: utf-8 -*-
"""Alpha模拟器核心类"""
import time
import httpx
from datetime import datetime
from typing import List, Tuple
from config.settings import settings
from models.entities import SimulationResult, TokenInfo
from core.database import DatabaseManager
from services.auth_service import AuthService
from services.alpha_service import AlphaService
from services.notification_service import NotificationService
class AlphaSimulator:
"""Alpha模拟器主类"""
def __init__(self):
self.db_manager = DatabaseManager()
self.auth_service = AuthService()
self.client = None
self.token_info = None
self.alpha_service = None
def __del__(self):
"""析构函数,确保数据库连接被关闭"""
if hasattr(self, 'db_manager'):
self.db_manager.close_connection()
def initialize(self) -> None:
"""初始化模拟器"""
self.client = httpx.Client()
self.login()
def login(self) -> TokenInfo:
"""登录并初始化alpha服务"""
self.token_info = self.auth_service.login(self.client)
self.alpha_service = AlphaService(self.client)
return self.token_info
def needs_token_refresh(self) -> bool:
"""检查是否需要刷新token"""
if not self.token_info:
return True
return self.token_info.expiry < settings.TOKEN_REFRESH_THRESHOLD
def load_alpha_list(self) -> List[str]:
"""从数据库加载未使用的alpha表达式"""
return self.db_manager.get_unused_alpha()
def run_batch_simulation(self, alpha_list: List[str]) -> Tuple[int, int]:
"""运行批量模拟"""
success_count = 0
fail_count = 0
for i in range(0, len(alpha_list), settings.BATCH_SIZE):
batch = alpha_list[i:i + settings.BATCH_SIZE]
print(f"\n开始处理第 {i // settings.BATCH_SIZE + 1} 批因子,共 {len(batch)}")
for expression in batch:
result = self._simulate_single_alpha(expression)
if result.status == "ok":
success_count += 1
else:
fail_count += 1
print(f"{i // settings.BATCH_SIZE + 1} 批处理完成")
self._print_summary(success_count, fail_count)
return success_count, fail_count
def _simulate_single_alpha(self, expression: str) -> SimulationResult:
"""模拟单个Alpha表达式"""
print(f"\n模拟因子: {expression}")
start_time = time.time()
try:
result = self.alpha_service.simulate_alpha(expression)
end_time = time.time()
time_consuming = round(end_time - start_time, 2)
simulation_result = SimulationResult(
expression=expression,
time_consuming=time_consuming,
status=result["status"],
timestamp=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
alpha_id=result.get("alpha_id"),
message=result.get("message", "")
)
if result["status"] == "ok":
print(f"✅ 模拟成功 - Alpha ID: {result['alpha_id']} - 耗时: {time_consuming}")
else:
print(f"❌ 模拟失败 - {result.get('message', '未知错误')}")
except Exception as e:
end_time = time.time()
time_consuming = round(end_time - start_time, 2)
simulation_result = SimulationResult(
expression=expression,
time_consuming=time_consuming,
status="err",
message=str(e),
timestamp=datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)
print(f"❌ 模拟异常 - {str(e)}")
# 保存结果并标记为已使用
self._save_simulation_result(simulation_result)
return simulation_result
def _save_simulation_result(self, result: SimulationResult) -> None:
"""保存模拟结果到数据库"""
self.db_manager.mark_alpha_used(result.expression)
self.db_manager.insert_simulation_result(result)
def _print_summary(self, success_count: int, fail_count: int) -> None:
"""打印总结信息"""
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"\n总计: 成功 {success_count} 个, 失败 {fail_count}")
print(f"完成时间: {now}")
print(f"所有结果已保存到 PostgreSQL 数据库 {settings.DATABASE_CONFIG['database']} 的 simulation 表中")
# 发送通知
NotificationService.send_to_gotify(success_count, fail_count)

@ -1,21 +1,45 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os """主程序入口"""
from managers.simulation_manager import AlphaSimulationManager
from utils.file_utils import load_alpha_list
import time
from core.simulator import AlphaSimulator
from config.settings import settings
from utils.helpers import retry_on_exception
def main():
"""主程序入口"""
# 待模拟因子列表
alpha_list = load_alpha_list('alpha.txt')
@retry_on_exception(max_retries=3, delay=5.0)
def main_loop(simulator: AlphaSimulator) -> None:
"""主循环"""
if simulator.needs_token_refresh():
print("Token需要刷新,重新登录...")
simulator.login()
alpha_list = simulator.load_alpha_list()
if not alpha_list: if not alpha_list:
print("未找到有效的因子表达式,请检查 alpha.txt 文件") print("暂无待处理的alpha表达式,10分钟后重新检查...")
time.sleep(600)
return return
# 创建模拟管理器并运行 print(f"共加载 {len(alpha_list)} 个需要模拟的因子表达式")
manager = AlphaSimulationManager() success_count, fail_count = simulator.run_batch_simulation(alpha_list)
results = manager.run_simulation(alpha_list, batch_size=3) print(f"本轮处理完成: 成功 {success_count} 个, 失败 {fail_count}")
def main():
"""主函数"""
simulator = AlphaSimulator()
simulator.initialize()
try:
while True:
main_loop(simulator)
print(f"等待{settings.CHECK_INTERVAL // 60}分钟后继续检查...")
time.sleep(settings.CHECK_INTERVAL)
except KeyboardInterrupt:
print("\n程序被用户中断")
except Exception as e:
print(f"程序执行异常: {e}")
raise
if __name__ == "__main__": if __name__ == "__main__":

@ -1,8 +0,0 @@
# -*- coding: utf-8 -*-
"""
管理模块 - 包含各种管理器类
"""
from .simulation_manager import AlphaSimulationManager
__all__ = ['AlphaSimulationManager']

@ -1,232 +0,0 @@
# -*- coding: utf-8 -*-
import time
import json
import os
from concurrent.futures import ThreadPoolExecutor, as_completed
from random import uniform
from typing import List, Dict, Any
from core.api_client import WorldQuantBrainSimulate
from core.models import SimulationResult
from utils.time_utils import format_time
from utils.file_utils import save_results_to_file, save_success_alpha
class AlphaSimulationManager:
def __init__(self, credentials_file='account.txt'):
self.credentials_file = credentials_file
self.results = []
"""模拟单个Alpha因子(线程安全)"""
def simulate_single_alpha(self, api: WorldQuantBrainSimulate, expression: str,
settings: Dict[str, Any] = None) -> SimulationResult:
alpha_start_time = time.time()
try:
# 模拟Alpha因子
simulation_result = api.simulate_alpha(expression, settings)
alpha_end_time = time.time()
time_consuming = alpha_end_time - alpha_start_time
# 根据模拟结果类型处理
if simulation_result["status"] == "success":
# 模拟成功的结果 - 直接使用原始metrics数据
metrics = simulation_result["metrics"]
result = SimulationResult(
expression=expression,
time_consuming=time_consuming,
formatted_time=format_time(time_consuming),
alpha_id=simulation_result["alpha_id"],
status="success",
description="/",
simulation_timestamp=time.strftime("%Y-%m-%d %H:%M:%S"),
metrics=metrics # 直接存储原始metrics数据
)
print(f"✓ 因子模拟成功: {expression}")
print(f" 耗时: {format_time(time_consuming)},Alpha ID: {simulation_result['alpha_id']}")
# 打印关键指标
self._print_success_metrics(metrics)
else:
# 模拟失败的结果(API返回的错误)
result = SimulationResult(
expression=expression,
time_consuming=time_consuming,
formatted_time=format_time(time_consuming),
alpha_id="/",
status="error",
description=simulation_result["message"],
simulation_timestamp=time.strftime("%Y-%m-%d %H:%M:%S"),
metrics=None
)
print(f"✗ 因子模拟失败: {expression}")
print(f" 耗时: {format_time(time_consuming)},错误: {simulation_result['message']}")
except Exception as e:
# 其他异常情况
alpha_end_time = time.time()
time_consuming = alpha_end_time - alpha_start_time
result = SimulationResult(
expression=expression,
time_consuming=time_consuming,
formatted_time=format_time(time_consuming),
alpha_id="/",
status="failed",
description=str(e),
simulation_timestamp=time.strftime("%Y-%m-%d %H:%M:%S"),
metrics=None
)
print(f"✗ 因子模拟异常: {expression}")
print(f" 耗时: {format_time(time_consuming)},异常: {str(e)}")
return result
"""打印成功因子的关键指标"""
def _print_success_metrics(self, metrics: Dict[str, Any]):
# 添加空值检查
if not metrics:
print(" 无指标数据")
return
print(" 关键指标 (训练集):")
# 从原始metrics数据中提取训练集指标
train_data = metrics.get('train', {}) or {}
key_metrics = [
('夏普比率', train_data.get('sharpe')),
('年化收益', train_data.get('returns')),
('最大回撤', train_data.get('drawdown')),
('换手率', train_data.get('turnover')),
('适应度', train_data.get('fitness')),
('PNL', train_data.get('pnl')),
]
for chinese_name, value in key_metrics:
if value is not None:
if isinstance(value, float):
value = f"{value:.4f}"
print(f" {chinese_name}: {value}") # 衡量风险调整后的收益
# 年化收益率
# 显示样本外测试的夏普比率(如果存在) # 最大亏损幅度
test_data = metrics.get('test', {}) or {} # 交易频率
if test_data.get('sharpe') is not None: # 策略适应度得分
print(f" 样本外夏普比率: {test_data.get('sharpe'):.4f}") # 净盈亏
"""模拟一批Alpha因子(3个一组)"""
def simulate_alpha_batch(self, alpha_batch: List[str], batch_number: int) -> List[SimulationResult]:
print(f"\n{'=' * 60}") # 只打印存在的指标
print(f"开始第 {batch_number} 批因子模拟 (共 {len(alpha_batch)} 个因子)") # 格式化浮点数显示
print(f"因子列表: {alpha_batch}")
print(f"{'=' * 60}")
batch_start_time = time.time()
batch_results = []
# 检查是否存在测试集夏普比率
# 创建API客户端实例(每个线程独立的客户端)
api = WorldQuantBrainSimulate(self.credentials_file)
try:
if api.login():
# 使用线程池执行3个因子的模拟
with ThreadPoolExecutor(max_workers=3) as executor:
# 提交所有任务
future_to_alpha = {
executor.submit(self.simulate_single_alpha, api, alpha): alpha
for alpha in alpha_batch
}
# 等待所有任务完成
for future in as_completed(future_to_alpha):
alpha = future_to_alpha[future]
try:
result = future.result()
batch_results.append(result)
except Exception as e:
print(f"因子 {alpha} 执行异常: {e}")
except Exception as e:
print(f"{batch_number} 批模拟过程中出错: {e}")
finally:
api.close()
batch_end_time = time.time()
batch_total_time = batch_end_time - batch_start_time
print(f"\n{batch_number} 批模拟完成!")
print(f"本批总耗时: {format_time(batch_total_time)}")
print(f"{'=' * 60}")
return batch_results
"""运行批量模拟"""
def run_simulation(self, alpha_list: List[str], batch_size: int = 3) -> List[SimulationResult]:
print("开始Alpha因子批量模拟...")
total_start_time = time.time()
# 将因子列表分成每批3个
batches = [alpha_list[i:i + batch_size] for i in range(0, len(alpha_list), batch_size)]
all_results = []
for i, batch in enumerate(batches, 1):
# 模拟当前批次
batch_results = self.simulate_alpha_batch(batch, i)
all_results.extend(batch_results)
# 如果不是最后一批,则等待3-5秒
if i < len(batches):
sleep_time = uniform(3, 5)
print(f"\n等待 {sleep_time:.2f} 秒后开始下一批...")
time.sleep(sleep_time)
total_end_time = time.time()
total_time = total_end_time - total_start_time
# 输出最终结果汇总
self.print_summary(all_results, total_time)
# 保存结果到文件
save_results_to_file(all_results)
return all_results
"""打印结果汇总"""
def print_summary(self, results: List[SimulationResult], total_time: float):
print(f"\n{'=' * 60}")
print("模拟结果汇总")
print(f"{'=' * 60}")
success_count = sum(1 for r in results if r.status == 'success')
error_count = sum(1 for r in results if r.status == 'error')
failed_count = sum(1 for r in results if r.status == 'failed')
print(f"总模拟因子数: {len(results)}")
print(f"成功: {success_count}")
print(f"模拟错误: {error_count}")
print(f"执行异常: {failed_count}")
print(f"总耗时: {format_time(total_time)}")
print(f"{'=' * 60}")
success_expression_list = []
for i, result in enumerate(results, 1):
status_icon = "" if result.status == 'success' else ""
if result.status == 'success':
success_expression_list.append(result.expression)
line_parts = [
f"{i}. {status_icon} {result.expression}",
f"状态: {result.status}",
f"耗时: {result.formatted_time}"
]
if result.alpha_id != '/':
line_parts.append(f"Alpha ID: {result.alpha_id}")
if result.status != 'success':
line_parts.append(f"原因: {result.description}")
print("\t".join(line_parts))
save_success_alpha(success_expression_list)

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
"""数据实体模型"""
from dataclasses import dataclass
from datetime import datetime
from typing import Optional
@dataclass
class SimulationResult:
"""模拟结果实体"""
expression: str
time_consuming: float
status: str # 'ok' or 'err'
timestamp: str
alpha_id: Optional[str] = None
message: Optional[str] = None
@dataclass
class AlphaExpression:
"""Alpha表达式实体"""
expression: str
unused: bool = True
created_time: Optional[datetime] = None
@dataclass
class TokenInfo:
"""认证令牌信息"""
token: str
expiry: int

@ -1,168 +0,0 @@
{
"schema": {
"name": "yearly-stats",
"title": "Yearly Stats",
"properties": [
{
"name": "year",
"title": "Year",
"type": "year"
},
{
"name": "pnl",
"title": "PnL",
"type": "amount"
},
{
"name": "bookSize",
"title": "Book Size",
"type": "amount"
},
{
"name": "longCount",
"title": "Long Count",
"type": "integer"
},
{
"name": "shortCount",
"title": "Short Count",
"type": "integer"
},
{
"name": "turnover",
"title": "Turnover",
"type": "percent"
},
{
"name": "sharpe",
"title": "Sharpe",
"type": "decimal"
},
{
"name": "returns",
"title": "Returns",
"type": "percent"
},
{
"name": "drawdown",
"title": "Drawdown",
"type": "percent"
},
{
"name": "margin",
"title": "Margin",
"type": "permyriad"
},
{
"name": "fitness",
"title": "Fitness",
"type": "decimal"
},
{
"name": "stage",
"title": "Stage",
"type": "string"
}
]
},
"records": [
[
"2018",
347052.0,
20000000,
1081,
1083,
0.3727,
1.54,
0.0365,
0.0156,
0.000196,
0.48,
"TRAIN"
],
[
"2019",
190205.0,
20000000,
1364,
1359,
0.3659,
0.83,
0.0189,
0.0353,
0.000103,
0.19,
"TRAIN"
],
[
"2020",
1554201.0,
20000000,
1348,
1340,
0.3639,
4.49,
0.1682,
0.0145,
0.000925,
3.05,
"TRAIN"
],
[
"2021",
584087.0,
20000000,
1435,
1424,
0.3652,
1.41,
0.0579,
0.0253,
0.000317,
0.56,
"TRAIN"
],
[
"2022",
31117.0,
20000000,
1441,
1434,
0.3446,
2.08,
0.0648,
0.004,
0.000376,
0.9,
"TRAIN"
],
[
"2022",
443804.0,
20000000,
1415,
1417,
0.3623,
1.19,
0.0464,
0.0349,
0.000256,
0.43,
"TEST"
],
[
"2023",
68779.0,
20000000,
1405,
1394,
0.3554,
6.22,
0.1323,
0.0019,
0.000744,
3.79,
"TEST"
]
]
}

@ -1,137 +0,0 @@
{
"id": "KP0WWZ6l",
"type": "REGULAR",
"author": "YC93384",
"settings": {
"instrumentType": "EQUITY",
"region": "USA",
"universe": "TOP3000",
"delay": 1,
"decay": 0,
"neutralization": "SUBINDUSTRY",
"truncation": 0.08,
"pasteurization": "ON",
"unitHandling": "VERIFY",
"nanHandling": "OFF",
"maxTrade": "OFF",
"language": "FASTEXPR",
"visualization": false,
"startDate": "2018-01-20",
"endDate": "2023-01-20",
"testPeriod": "P1Y"
},
"regular": {
"code": "rank(ts_sum(vec_avg(nws12_afterhsz_sl), 60)) * 0.7 + rank(-ts_delta(close, 2)) * 0.3",
"description": null,
"operatorCount": 9
},
"dateCreated": "2025-11-13T09:22:47-05:00",
"dateSubmitted": null,
"dateModified": "2025-11-13T09:22:47-05:00",
"name": null,
"favorite": false,
"hidden": false,
"color": null,
"category": null,
"tags": [],
"classifications": [],
"grade": "INFERIOR",
"stage": "IS",
"status": "UNSUBMITTED",
"is": {
"pnl": 3219244,
"bookSize": 20000000,
"longCount": 1332,
"shortCount": 1328,
"turnover": 0.3657,
"returns": 0.0651,
"drawdown": 0.0353,
"margin": 0.000356,
"sharpe": 1.93,
"fitness": 0.81,
"startDate": "2018-01-20",
"checks": [
{
"name": "LOW_SHARPE",
"result": "PASS",
"limit": 1.25,
"value": 1.93
},
{
"name": "LOW_FITNESS",
"result": "FAIL",
"limit": 1.0,
"value": 0.81
},
{
"name": "LOW_TURNOVER",
"result": "PASS",
"limit": 0.01,
"value": 0.3657
},
{
"name": "HIGH_TURNOVER",
"result": "PASS",
"limit": 0.7,
"value": 0.3657
},
{
"name": "CONCENTRATED_WEIGHT",
"result": "PASS"
},
{
"name": "LOW_SUB_UNIVERSE_SHARPE",
"result": "PASS",
"limit": 0.84,
"value": 1.7
},
{
"name": "SELF_CORRELATION",
"result": "PENDING"
},
{
"name": "MATCHES_COMPETITION",
"result": "PASS",
"competitions": [
{
"id": "challenge",
"name": "Challenge"
}
]
}
]
},
"os": null,
"train": {
"pnl": 2718449,
"bookSize": 20000000,
"longCount": 1311,
"shortCount": 1306,
"turnover": 0.3665,
"returns": 0.0689,
"drawdown": 0.0353,
"margin": 0.000376,
"fitness": 0.92,
"sharpe": 2.13,
"startDate": "2018-01-20"
},
"test": {
"pnl": 512583,
"bookSize": 20000000,
"longCount": 1415,
"shortCount": 1416,
"turnover": 0.362,
"returns": 0.0509,
"drawdown": 0.0349,
"margin": 0.000281,
"fitness": 0.5,
"sharpe": 1.33,
"startDate": "2022-01-20"
},
"prod": null,
"competitions": null,
"themes": null,
"pyramids": null,
"pyramidThemes": null,
"team": null
}

@ -1,22 +0,0 @@
{
"id": "3q4OCMgw4MFa8k16tdsYLml",
"type": "REGULAR",
"settings": {
"instrumentType": "EQUITY",
"region": "USA",
"universe": "TOP3000",
"delay": 1,
"decay": 0,
"neutralization": "SUBINDUSTRY",
"truncation": 0.08,
"pasteurization": "ON",
"unitHandling": "VERIFY",
"nanHandling": "OFF",
"maxTrade": "OFF",
"language": "FASTEXPR",
"visualization": false
},
"regular": "rank(ts_sum(vec_avg(nws12_afterhsz_sl), 60)) * 0.7 + rank(-ts_delta(close, 2)) * 0.3",
"status": "COMPLETE",
"alpha": "KP0WWZ6l"
}

@ -0,0 +1,714 @@
aiobotocore @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_b3e4znaej2/croot/aiobotocore_1680004294920/work
aiofiles==24.1.0
aiohappyeyeballs==2.6.1
aiohttp==3.11.14
aioitertools @ file:///tmp/build/80754af9/aioitertools_1607109665762/work
aiosignal @ file:///tmp/build/80754af9/aiosignal_1637843061372/work
aiosqlite @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_13w97vul7u/croot/aiosqlite_1683773912122/work
alabaster @ file:///home/ktietz/src/ci/alabaster_1611921544520/work
altgraph==0.17.4
anaconda-catalogs @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_737qok84ed/croot/anaconda-catalogs_1685727302903/work
anaconda-client==1.11.3
anaconda-navigator==2.4.2
anaconda-project @ file:///Users/ec2-user/ci_py311/anaconda-project_1678395481364/work
annotated-types==0.7.0
anyio==3.7.1
appdirs==1.4.4
applaunchservices @ file:///Users/ec2-user/ci_py311/applaunchservices_1678390181983/work
appnope @ file:///Users/ec2-user/ci_py311/appnope_1678317440516/work
appscript @ file:///Users/ec2-user/ci_py311/appscript_1678390203562/work
argon2-cffi @ file:///opt/conda/conda-bld/argon2-cffi_1645000214183/work
argon2-cffi-bindings @ file:///Users/ec2-user/ci_py311/argon2-cffi-bindings_1678317076583/work
arrow @ file:///Users/ec2-user/ci_py311/arrow_1678325845580/work
art==6.4
astroid @ file:///Users/ec2-user/ci_py311/astroid_1678323235198/work
astropy @ file:///Users/ec2-user/ci_py311_2/astropy_1679335070862/work
asttokens @ file:///opt/conda/conda-bld/asttokens_1646925590279/work
astunparse==1.6.3
async-timeout @ file:///Users/ec2-user/ci_py311/async-timeout_1678320112070/work
atomicwrites==1.4.0
attrs==25.3.0
Automat @ file:///tmp/build/80754af9/automat_1600298431173/work
autopep8 @ file:///opt/conda/conda-bld/autopep8_1650463822033/work
Babel @ file:///Users/ec2-user/ci_py311/babel_1678318085010/work
backcall @ file:///home/ktietz/src/ci/backcall_1611930011877/work
backoff==2.2.1
backports.functools-lru-cache @ file:///tmp/build/80754af9/backports.functools_lru_cache_1618170165463/work
backports.tempfile @ file:///home/linux1/recipes/ci/backports.tempfile_1610991236607/work
backports.weakref==1.0.post1
base58==2.1.1
bcrypt @ file:///Users/ec2-user/ci_py311/bcrypt_1678325873219/work
beautifulsoup4==4.14.0
better-proxy==1.1.5
betterproto2==0.5.1
bidict==0.23.1
binaryornot @ file:///tmp/build/80754af9/binaryornot_1617751525010/work
bip39==0.0.2
bitarray==2.9.2
black @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_1f1pcodmuo/croot/black_1680737253550/work
bleach @ file:///opt/conda/conda-bld/bleach_1641577558959/work
blinker==1.7.0
bokeh @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_f0dguf6k4i/croot/bokeh_1684534020835/work
boltons @ file:///Users/ec2-user/ci_py311/boltons_1678396074811/work
boto3 @ file:///Users/ec2-user/ci_py311_2/boto3_1679335351182/work
botocore @ file:///Users/ec2-user/ci_py311/botocore_1678320133200/work
Bottleneck @ file:///Users/ec2-user/ci_py311/bottleneck_1678322312632/work
Brotli==1.1.0
brotlipy==0.7.0
bs4==0.0.2
build==1.2.2.post1
buildozer==1.5.0
cairocffi==1.6.1
CairoSVG==2.7.1
candlelite==1.0.17
canoser==0.8.2
captchatools==1.5.0
certifi==2025.8.3
cffi @ file:///Users/ec2-user/ci_py311/cffi_1678315312775/work
chardet @ file:///Users/ec2-user/ci_py311/chardet_1678326102860/work
charset-normalizer @ file:///tmp/build/80754af9/charset-normalizer_1630003229654/work
ci-info==0.3.0
ckzg==1.0.1
click @ file:///Users/ec2-user/ci_py311/click_1678318124837/work
cloudpickle @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_c57ujq_pgm/croot/cloudpickle_1683040025620/work
clyent==1.2.2
colorama @ file:///Users/ec2-user/ci_py311/colorama_1678320227414/work
colorcet @ file:///Users/ec2-user/ci_py311/colorcet_1678380145131/work
comm @ file:///Users/ec2-user/ci_py311/comm_1678317779525/work
conda @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_a9qfrev42r/croot/conda_1685025193092/work
conda-build @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_e5ocr04fqn/croot/conda-build_1685026138121/work
conda-content-trust @ file:///Users/ec2-user/ci_py311/conda-content-trust_1678409283937/work
conda-libmamba-solver @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_b7jucd8kvj/croot/conda-libmamba-solver_1685032330942/work/src
conda-pack @ file:///tmp/build/80754af9/conda-pack_1611163042455/work
conda-package-handling @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_f61sssj1s3/croot/conda-package-handling_1685024797154/work
conda-repo-cli==1.0.41
conda-token @ file:///Users/paulyim/miniconda3/envs/c3i/conda-bld/conda-token_1662660369760/work
conda-verify==3.4.2
conda_index @ file:///Users/ec2-user/ci_py311/conda-index_1678409305677/work
conda_package_streaming @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_78ue32m8ay/croot/conda-package-streaming_1685019689310/work
configobj==5.0.8
configparser==6.0.0
constantly==15.1.0
contourpy @ file:///Users/ec2-user/ci_py311/contourpy_1678322361099/work
cookiecutter @ file:///opt/conda/conda-bld/cookiecutter_1649151442564/work
cryptography @ file:///Users/ec2-user/ci_py311_2/cryptography_1679335457662/work
cssselect==1.1.0
cssselect2==0.7.0
cycler @ file:///tmp/build/80754af9/cycler_1637851556182/work
Cython==3.0.11
cytoolz @ file:///Users/ec2-user/ci_py311/cytoolz_1678326214370/work
dask @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_ccdxmmxbox/croot/dask-core_1686782920612/work
dataclasses-json==0.6.7
DataRecorder==3.6.2
datashader @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_93l60mzvvb/croot/datashader_1685542975569/work
datashape==0.5.4
debugpy @ file:///Users/ec2-user/ci_py311/debugpy_1678317801115/work
decorator @ file:///opt/conda/conda-bld/decorator_1643638310831/work
defusedxml @ file:///tmp/build/80754af9/defusedxml_1615228127516/work
Deprecated==1.2.18
diff-match-patch @ file:///Users/ktietz/demo/mc3/conda-bld/diff-match-patch_1630511840874/work
dill @ file:///Users/ec2-user/ci_py311/dill_1678323290904/work
distlib==0.3.9
distributed @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_95i88jlqtp/croot/distributed_1686866052419/work
distro==1.9.0
dnspython==2.4.1
docstring-to-markdown @ file:///Users/ec2-user/ci_py311/docstring-to-markdown_1678326320721/work
docutils==0.22.1
docx==0.2.4
DownloadKit==2.0.7
DrissionPage==4.1.0.17
dukpy==0.4.0
easygui==0.98.3
email-validator==2.0.0.post2
entrypoints @ file:///Users/ec2-user/ci_py311/entrypoints_1678316169365/work
epcpy==0.1.7
et-xmlfile==1.1.0
etelemetry==0.3.1
eth-account==0.11.2
eth-hash==0.7.0
eth-keyfile==0.8.1
eth-keys==0.5.1
eth-rlp==1.0.1
eth-typing==4.2.1
eth-utils==4.1.0
eth_abi==5.1.0
executing @ file:///opt/conda/conda-bld/executing_1646925071911/work
fake-useragent==1.5.1
fastapi==0.104.1
fastjsonschema @ file:///Users/ec2-user/ci_py311_2/python-fastjsonschema_1679338737111/work
filelock==3.16.1
filetype==1.2.0
fitz==0.0.1.dev2
flake8 @ file:///Users/ec2-user/ci_py311/flake8_1678326404511/work
Flask @ file:///Users/ec2-user/ci_py311/flask_1678380788105/work
fonttools==4.25.0
fqdn==1.5.1
frozenlist @ file:///Users/ec2-user/ci_py311/frozenlist_1678318685088/work
fsspec @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_d9zxascxg8/croot/fsspec_1679418997424/work
future @ file:///Users/ec2-user/ci_py311_2/future_1679335881731/work
genshinhelper==2.1.3
gensim @ file:///Users/ec2-user/ci_py311/gensim_1678412014794/work
glob2 @ file:///home/linux1/recipes/ci/glob2_1610991677669/work
gmpy2 @ file:///Users/ec2-user/ci_py311/gmpy2_1678380831980/work
gql==3.5.3
graphql-core==3.2.6
greenlet==3.1.1
grpclib==0.4.8
h11==0.16.0
h2==4.1.0
h5py @ file:///Users/ec2-user/ci_py311/h5py_1678381005308/work
HeapDict @ file:///Users/ktietz/demo/mc3/conda-bld/heapdict_1630598515714/work
hexbytes==0.3.1
holoviews @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_7a7dicrx1g/croot/holoviews_1686339350598/work
hpack==4.0.0
httpcore==1.0.9
httplib2==0.22.0
httptools==0.6.0
httpx==0.25.2
httpx-sse==0.4.0
hvplot @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_4dben4g_th/croot/hvplot_1685998195310/work
hyperframe==6.0.1
hyperlink @ file:///tmp/build/80754af9/hyperlink_1610130746837/work
idna @ file:///Users/ec2-user/ci_py311/idna_1678315819133/work
ifaddr==0.2.0
imagecodecs @ file:///Users/ec2-user/ci_py311_2/imagecodecs_1679336141260/work
imageio @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_47v6nbs3l9/croot/imageio_1687264946242/work
imagesize @ file:///Users/ec2-user/ci_py311/imagesize_1678377399148/work
imap-tools==1.10.0
imbalanced-learn @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_a1ju_tsc7c/croot/imbalanced-learn_1685020900729/work
importlib-metadata @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_81_20mq0d8/croot/importlib-metadata_1678997090664/work
incremental @ file:///tmp/build/80754af9/incremental_1636629750599/work
inflection==0.5.1
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
intake @ file:///Users/ec2-user/ci_py311_2/intake_1679336302724/work
intervaltree @ file:///Users/ktietz/demo/mc3/conda-bld/intervaltree_1630511889664/work
ipykernel @ file:///Users/ec2-user/ci_py311/ipykernel_1678318220696/work
ipython @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_cd4ia5pr17/croot/ipython_1680701875298/work
ipython-genutils @ file:///tmp/build/80754af9/ipython_genutils_1606773439826/work
ipywidgets @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_f5atknkudc/croot/ipywidgets_1679394812720/work
isodate==0.6.1
isoduration==20.11.0
isort @ file:///tmp/build/80754af9/isort_1628603791788/work
itemadapter @ file:///tmp/build/80754af9/itemadapter_1626442940632/work
itemloaders @ file:///opt/conda/conda-bld/itemloaders_1646805235997/work
itsdangerous==2.2.0
jaraco.classes @ file:///tmp/build/80754af9/jaraco.classes_1620983179379/work
jedi @ file:///Users/ec2-user/ci_py311_2/jedi_1679336327335/work
jellyfish @ file:///Users/ec2-user/ci_py311/jellyfish_1678392216202/work
Jinja2==3.1.6
jinja2-time @ file:///opt/conda/conda-bld/jinja2-time_1649251842261/work
jiter==0.8.2
jittor==1.3.8.5
jmespath @ file:///Users/ktietz/demo/mc3/conda-bld/jmespath_1630583964805/work
joblib @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_dfriz0qjwt/croot/joblib_1685113297703/work
Js2Py_3.13==0.74.1
json5 @ file:///tmp/build/80754af9/json5_1624432770122/work
jsonalias==0.1.1
jsonpatch==1.33
jsonpointer==2.1
jsonschema==4.23.0
jsonschema-specifications==2025.4.1
jtorch==0.1.7
jupyter @ file:///Users/ec2-user/ci_py311/jupyter_1678377791770/work
jupyter-console @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_e8qcp1kdie/croot/jupyter_console_1679999714867/work
jupyter-events @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_f0yqwpn5u1/croot/jupyter_events_1684268046871/work
jupyter-ydoc @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_79b9hk1z3q/croot/jupyter_ydoc_1683747244664/work
jupyter_client @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_5e4bbpqn9e/croot/jupyter_client_1680171866753/work
jupyter_core @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_b82fz_h369/croot/jupyter_core_1679906581737/work
jupyter_server @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_b7pddqvxoj/croot/jupyter_server_1686059483368/work
jupyter_server_fileid @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_b0lffopjbp/croot/jupyter_server_fileid_1684273621123/work
jupyter_server_terminals @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_257krljdmq/croot/jupyter_server_terminals_1686870730796/work
jupyter_server_ydoc @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_6848h2a_93/croot/jupyter_server_ydoc_1686768718335/work
jupyterlab @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_502x016ek3/croot/jupyterlab_1686179671461/work
jupyterlab-pygments @ file:///tmp/build/80754af9/jupyterlab_pygments_1601490720602/work
jupyterlab-widgets @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_9btffb27id/croot/jupyterlab_widgets_1679055288818/work
jupyterlab_server @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_9039tf6tpv/croot/jupyterlab_server_1680792539169/work
kaitaistruct==0.10
keyring @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_2ds0bchnl2/croot/keyring_1678999223818/work
Kivy==2.3.0
Kivy-Garden==0.1.5
kiwisolver @ file:///Users/ec2-user/ci_py311/kiwisolver_1678322457192/work
langchain==0.3.14
langchain-community==0.3.14
langchain-core==0.3.29
langchain-text-splitters==0.3.4
langsmith==0.2.10
lazy-object-proxy @ file:///Users/ec2-user/ci_py311/lazy-object-proxy_1678322504286/work
lazy_loader @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_02apt1h75k/croot/lazy_loader_1687264081288/work
libarchive-c @ file:///tmp/build/80754af9/python-libarchive-c_1617780486945/work
libmambapy @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_65seb320zf/croot/mamba-split_1680093070986/work/libmambapy
linkify-it-py @ file:///Users/ec2-user/ci_py311/linkify-it-py_1678413480728/work
llvmlite @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_39tj5og13d/croot/llvmlite_1683555130919/work
lmdb @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_88zbo0vn66/croot/python-lmdb_1682522360781/work
locket @ file:///Users/ec2-user/ci_py311/locket_1678322541585/work
loguru==0.7.2
looseversion==1.3.0
lru-dict==1.2.0
lxml==6.0.2
lz4 @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_7fl2lzb5wh/croot/lz4_1686057901919/work
m3u8==6.0.0
macholib==1.16.3
Markdown @ file:///Users/ec2-user/ci_py311/markdown_1678377870854/work
markdown-it-py @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_43xjt6hz0x/croot/markdown-it-py_1684279911135/work
markdown2==2.5.4
MarkupSafe==3.0.3
marshmallow==3.24.1
matplotlib @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_41fhwn4tj9/croot/matplotlib-suite_1679593479845/work
matplotlib-inline @ file:///Users/ec2-user/ci_py311/matplotlib-inline_1678317544666/work
mccabe @ file:///opt/conda/conda-bld/mccabe_1644221741721/work
mdit-py-plugins @ file:///Users/ec2-user/ci_py311/mdit-py-plugins_1678417716573/work
mdurl @ file:///Users/ec2-user/ci_py311/mdurl_1678381820326/work
mistune @ file:///Users/ec2-user/ci_py311/mistune_1678317272228/work
mmh3==4.1.0
mnemonic==0.21
modulegraph==0.19.6
more-itertools @ file:///tmp/build/80754af9/more-itertools_1637733554872/work
mpmath==1.2.1
msgpack @ file:///Users/ec2-user/ci_py311/msgpack-python_1678318264150/work
multidict @ file:///Users/ec2-user/ci_py311/multidict_1678318765630/work
multipledispatch @ file:///Users/ec2-user/ci_py311/multipledispatch_1678392901644/work
munkres==1.1.4
mutf8==1.0.6
mypy==1.18.2
mypy_extensions==1.1.0
names==0.3.0
navigator-updater==0.4.0
nbclassic @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_e9be4uk5qu/croot/nbclassic_1681756175065/work
nbclient @ file:///Users/ec2-user/ci_py311/nbclient_1678317300721/work
nbconvert @ file:///Users/ec2-user/ci_py311/nbconvert_1678317567483/work
nbformat @ file:///Users/ec2-user/ci_py311/nbformat_1678317010390/work
nest-asyncio @ file:///Users/ec2-user/ci_py311/nest-asyncio_1678316288195/work
networkx @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_1a72gktq2s/croot/networkx_1678964337061/work
nibabel==5.1.0
nicegui==2.24.1
nipype==1.8.6
nltk @ file:///opt/conda/conda-bld/nltk_1645628263994/work
nodeenv==1.9.1
notebook @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_be_2kh1kd4/croot/notebook_1681756176866/work
notebook_shim @ file:///Users/ec2-user/ci_py311/notebook-shim_1678318293647/work
numba @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_93pzbiav_e/croot/numba_1684245526578/work
numexpr @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_1b50c1js9s/croot/numexpr_1683227065029/work
numpy==1.26.3
numpydoc @ file:///Users/ec2-user/ci_py311/numpydoc_1678393034712/work
OdooRPC==0.10.1
okx==2.1.1
okx-api==1.0.5
ollama==0.4.5
openai==1.59.6
opencv-python==4.8.1.78
openpyxl==3.0.10
orjson==3.10.13
outcome==1.3.0.post0
packaging==24.2
pandas==1.5.3
pandocfilters @ file:///opt/conda/conda-bld/pandocfilters_1643405455980/work
panel @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_dfq8ysliwf/croot/panel_1686058338704/work
param @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_eb_xu6rgzh/croot/param_1684915322419/work
parsel @ file:///Users/ec2-user/ci_py311/parsel_1678382184303/work
parsimonious==0.10.0
parso @ file:///opt/conda/conda-bld/parso_1641458642106/work
partd @ file:///opt/conda/conda-bld/partd_1647245470509/work
pathlib @ file:///Users/ktietz/demo/mc3/conda-bld/pathlib_1629713961906/work
pathspec @ file:///Users/ec2-user/ci_py311_2/pathspec_1679337122817/work
patsy==0.5.3
paux==1.0.14
pdfminer==20191125
pdfminer3k==1.3.4
pdfparanoia==0.0.17
pendulum==3.0.0
pep8==1.7.1
pexpect @ file:///tmp/build/80754af9/pexpect_1605563209008/work
pickleshare @ file:///tmp/build/80754af9/pickleshare_1606932040724/work
pika==1.3.2
Pillow==9.4.0
pkginfo @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_d976p03z5u/croot/pkginfo_1679431175529/work
platformdirs==4.3.6
playwright==1.50.0
plotly @ file:///Users/ec2-user/ci_py311/plotly_1678382250051/work
pluggy @ file:///Users/ec2-user/ci_py311/pluggy_1678315400971/work
ply==3.11
pooch @ file:///tmp/build/80754af9/pooch_1623324770023/work
potracer==0.0.4
poyo @ file:///tmp/build/80754af9/poyo_1617751526755/work
prometheus-client @ file:///Users/ec2-user/ci_py311_2/prometheus_client_1679340232148/work
prompt-toolkit @ file:///Users/ec2-user/ci_py311/prompt-toolkit_1678317707969/work
propcache==0.3.0
Protego @ file:///tmp/build/80754af9/protego_1598657180827/work
protobuf==5.26.1
prov==2.0.0
pscript==0.7.7
psutil @ file:///Users/ec2-user/ci_py311_2/psutil_1679337242143/work
psycopg2==2.9.9
ptyprocess @ file:///tmp/build/80754af9/ptyprocess_1609355006118/work/dist/ptyprocess-0.7.0-py2.py3-none-any.whl
pure-eval @ file:///opt/conda/conda-bld/pure_eval_1646925070566/work
py-cpuinfo @ file:///Users/ktietz/demo/mc3/conda-bld/py-cpuinfo_1629480366017/work
py2app==0.28.6
pyarrow==11.0.0
pyasn1 @ file:///Users/ktietz/demo/mc3/conda-bld/pyasn1_1629708007385/work
pyasn1-modules==0.2.8
pycodestyle @ file:///Users/ec2-user/ci_py311/pycodestyle_1678324331308/work
pycosat @ file:///Users/ec2-user/ci_py311/pycosat_1678378899646/work
pycparser @ file:///tmp/build/80754af9/pycparser_1636541352034/work
pycryptodome==3.19.0
pyct @ file:///Users/ec2-user/ci_py311/pyct_1678378955854/work
pycurl==7.45.2
pydantic==2.11.9
pydantic-extra-types==2.0.0
pydantic-settings==2.7.1
pydantic_core==2.33.2
PyDispatcher==2.0.5
pydocstyle @ file:///Users/ec2-user/ci_py311/pydocstyle_1678378981125/work
pydoll-python==1.3.3
pydot==1.4.2
pyee==12.0.0
pyerfa @ file:///Users/ec2-user/ci_py311/pyerfa_1678379006730/work
pyflakes @ file:///Users/ec2-user/ci_py311/pyflakes_1678324357242/work
Pygments @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_cflayrfqsi/croot/pygments_1684279981084/work
PyICU==2.12
pyinstaller==6.2.0
pyinstaller-hooks-contrib==2023.10
pyjsparser==2.7.1
PyJWT @ file:///Users/ec2-user/ci_py311/pyjwt_1678379090382/work
pylint @ file:///Users/ec2-user/ci_py311/pylint_1678379112162/work
pylint-venv @ file:///Users/ec2-user/ci_py311/pylint-venv_1678393629931/work
pyls-spyder==0.4.0
PyMuPDF==1.23.6
PyMuPDFb==1.23.6
pynanosvg==0.3.1
pyobjc==10.3.1
pyobjc-core==10.3.1
pyobjc-framework-Accessibility==10.3.1
pyobjc-framework-Accounts==10.3.1
pyobjc-framework-AddressBook==10.3.1
pyobjc-framework-AdServices==10.3.1
pyobjc-framework-AdSupport==10.3.1
pyobjc-framework-AppleScriptKit==10.3.1
pyobjc-framework-AppleScriptObjC==10.3.1
pyobjc-framework-ApplicationServices==10.3.1
pyobjc-framework-AppTrackingTransparency==10.3.1
pyobjc-framework-AudioVideoBridging==10.3.1
pyobjc-framework-AuthenticationServices==10.3.1
pyobjc-framework-AutomaticAssessmentConfiguration==10.3.1
pyobjc-framework-Automator==10.3.1
pyobjc-framework-AVFoundation==10.3.1
pyobjc-framework-AVKit==10.3.1
pyobjc-framework-AVRouting==10.3.1
pyobjc-framework-BackgroundAssets==10.3.1
pyobjc-framework-BusinessChat==10.3.1
pyobjc-framework-CalendarStore==10.3.1
pyobjc-framework-CallKit==10.3.1
pyobjc-framework-CFNetwork==10.3.1
pyobjc-framework-ClassKit==10.3.1
pyobjc-framework-CloudKit==10.3.1
pyobjc-framework-Cocoa==10.3.1
pyobjc-framework-Collaboration==10.3.1
pyobjc-framework-ColorSync==10.3.1
pyobjc-framework-Contacts==10.3.1
pyobjc-framework-ContactsUI==10.3.1
pyobjc-framework-CoreAudio==10.3.1
pyobjc-framework-CoreAudioKit==10.3.1
pyobjc-framework-CoreBluetooth==10.3.1
pyobjc-framework-CoreData==10.3.1
pyobjc-framework-CoreHaptics==10.3.1
pyobjc-framework-CoreLocation==10.3.1
pyobjc-framework-CoreMedia==10.3.1
pyobjc-framework-CoreMediaIO==10.3.1
pyobjc-framework-CoreMIDI==10.3.1
pyobjc-framework-CoreML==10.3.1
pyobjc-framework-CoreMotion==10.3.1
pyobjc-framework-CoreServices==10.3.1
pyobjc-framework-CoreSpotlight==10.3.1
pyobjc-framework-CoreText==10.3.1
pyobjc-framework-CoreWLAN==10.3.1
pyobjc-framework-CryptoTokenKit==10.3.1
pyobjc-framework-DataDetection==10.3.1
pyobjc-framework-DeviceCheck==10.3.1
pyobjc-framework-DictionaryServices==10.3.1
pyobjc-framework-DiscRecording==10.3.1
pyobjc-framework-DiscRecordingUI==10.3.1
pyobjc-framework-DiskArbitration==10.3.1
pyobjc-framework-DVDPlayback==10.3.1
pyobjc-framework-EventKit==10.3.1
pyobjc-framework-ExceptionHandling==10.3.1
pyobjc-framework-ExecutionPolicy==10.3.1
pyobjc-framework-ExtensionKit==10.3.1
pyobjc-framework-ExternalAccessory==10.3.1
pyobjc-framework-FileProvider==10.3.1
pyobjc-framework-FileProviderUI==10.3.1
pyobjc-framework-FinderSync==10.3.1
pyobjc-framework-FSEvents==10.3.1
pyobjc-framework-GameCenter==10.3.1
pyobjc-framework-GameController==10.3.1
pyobjc-framework-GameKit==10.3.1
pyobjc-framework-GameplayKit==10.3.1
pyobjc-framework-HealthKit==10.3.1
pyobjc-framework-ImageCaptureCore==10.3.1
pyobjc-framework-InputMethodKit==10.3.1
pyobjc-framework-InstallerPlugins==10.3.1
pyobjc-framework-InstantMessage==10.3.1
pyobjc-framework-Intents==10.3.1
pyobjc-framework-IntentsUI==10.3.1
pyobjc-framework-IOBluetooth==10.3.1
pyobjc-framework-IOBluetoothUI==10.3.1
pyobjc-framework-IOSurface==10.3.1
pyobjc-framework-iTunesLibrary==10.3.1
pyobjc-framework-KernelManagement==10.3.1
pyobjc-framework-LatentSemanticMapping==10.3.1
pyobjc-framework-LaunchServices==10.3.1
pyobjc-framework-libdispatch==10.3.1
pyobjc-framework-libxpc==10.3.1
pyobjc-framework-LinkPresentation==10.3.1
pyobjc-framework-LocalAuthentication==10.3.1
pyobjc-framework-LocalAuthenticationEmbeddedUI==10.3.1
pyobjc-framework-MailKit==10.3.1
pyobjc-framework-MapKit==10.3.1
pyobjc-framework-MediaAccessibility==10.3.1
pyobjc-framework-MediaLibrary==10.3.1
pyobjc-framework-MediaPlayer==10.3.1
pyobjc-framework-MediaToolbox==10.3.1
pyobjc-framework-Metal==10.3.1
pyobjc-framework-MetalFX==10.3.1
pyobjc-framework-MetalKit==10.3.1
pyobjc-framework-MetalPerformanceShaders==10.3.1
pyobjc-framework-MetalPerformanceShadersGraph==10.3.1
pyobjc-framework-MetricKit==10.3.1
pyobjc-framework-MLCompute==10.3.1
pyobjc-framework-ModelIO==10.3.1
pyobjc-framework-MultipeerConnectivity==10.3.1
pyobjc-framework-NaturalLanguage==10.3.1
pyobjc-framework-NetFS==10.3.1
pyobjc-framework-Network==10.3.1
pyobjc-framework-NetworkExtension==10.3.1
pyobjc-framework-NotificationCenter==10.3.1
pyobjc-framework-OpenDirectory==10.3.1
pyobjc-framework-OSAKit==10.3.1
pyobjc-framework-OSLog==10.3.1
pyobjc-framework-PassKit==10.3.1
pyobjc-framework-PencilKit==10.3.1
pyobjc-framework-PHASE==10.3.1
pyobjc-framework-Photos==10.3.1
pyobjc-framework-PhotosUI==10.3.1
pyobjc-framework-PreferencePanes==10.3.1
pyobjc-framework-PushKit==10.3.1
pyobjc-framework-Quartz==10.3.1
pyobjc-framework-QuickLookThumbnailing==10.3.1
pyobjc-framework-ReplayKit==10.3.1
pyobjc-framework-SafariServices==10.3.1
pyobjc-framework-SafetyKit==10.3.1
pyobjc-framework-SceneKit==10.3.1
pyobjc-framework-ScreenCaptureKit==10.3.1
pyobjc-framework-ScreenSaver==10.3.1
pyobjc-framework-ScreenTime==10.3.1
pyobjc-framework-ScriptingBridge==10.3.1
pyobjc-framework-SearchKit==10.3.1
pyobjc-framework-Security==10.3.1
pyobjc-framework-SecurityFoundation==10.3.1
pyobjc-framework-SecurityInterface==10.3.1
pyobjc-framework-ServiceManagement==10.3.1
pyobjc-framework-SharedWithYou==10.3.1
pyobjc-framework-SharedWithYouCore==10.3.1
pyobjc-framework-ShazamKit==10.3.1
pyobjc-framework-Social==10.3.1
pyobjc-framework-SoundAnalysis==10.3.1
pyobjc-framework-Speech==10.3.1
pyobjc-framework-SpriteKit==10.3.1
pyobjc-framework-StoreKit==10.3.1
pyobjc-framework-SyncServices==10.3.1
pyobjc-framework-SystemConfiguration==10.3.1
pyobjc-framework-SystemExtensions==10.3.1
pyobjc-framework-ThreadNetwork==10.3.1
pyobjc-framework-UniformTypeIdentifiers==10.3.1
pyobjc-framework-UserNotifications==10.3.1
pyobjc-framework-UserNotificationsUI==10.3.1
pyobjc-framework-VideoSubscriberAccount==10.3.1
pyobjc-framework-VideoToolbox==10.3.1
pyobjc-framework-Virtualization==10.3.1
pyobjc-framework-Vision==10.3.1
pyobjc-framework-WebKit==10.3.1
pyodbc @ file:///Users/ec2-user/ci_py311/pyodbc_1678420730897/work
pyOpenSSL @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_19gfn1ib_u/croot/pyopenssl_1678965300171/work
pyotp==2.9.0
pyparsing @ file:///Users/ec2-user/ci_py311/pyparsing_1678322828710/work
PyPDF2==1.26.0
PyPDF4==1.27.0
pyproject_hooks==1.2.0
PyQt5-sip==12.11.0
PyQt6==6.4.2
pyqt6-plugins==6.4.2.2.3
PyQt6-Qt6==6.4.3
PyQt6-sip==13.6.0
pyqt6-tools==6.4.2.3.3
PyQt6-WebEngine==6.6.0
PyQt6-WebEngine-Qt6==6.6.0
pyright==1.1.405
pyrsistent @ file:///Users/ec2-user/ci_py311/pyrsistent_1678316053523/work
PySocks @ file:///Users/ec2-user/ci_py311/pysocks_1678315868424/work
pysui==0.85.0
pysui-fastcrypto==0.7.0
pytest @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_bcnsxh_kaf/croot/pytest_1684171610545/work
python-barcode==0.15.1
python-dateutil @ file:///tmp/build/80754af9/python-dateutil_1626374649649/work
python-dotenv==1.0.0
python-engineio==4.12.2
python-json-logger @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_49p5x2bjzn/croot/python-json-logger_1683823814668/work
python-lsp-black @ file:///Users/ec2-user/ci_py311/python-lsp-black_1678393907972/work
python-lsp-jsonrpc==1.0.0
python-lsp-server @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_1fkjjx0yhx/croot/python-lsp-server_1681930400163/work
python-multipart==0.0.6
python-slugify @ file:///tmp/build/80754af9/python-slugify_1620405669636/work
python-snappy @ file:///Users/ec2-user/ci_py311/python-snappy_1678388765172/work
python-socketio==5.13.0
python-socks==2.7.1
pytoolconfig @ file:///Users/ec2-user/ci_py311/pytoolconfig_1678324412360/work
pytz @ file:///Users/ec2-user/ci_py311/pytz_1678318034461/work
pyunormalize==15.1.0
pyviz-comms @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_13yvjs0iia/croot/pyviz_comms_1685030724461/work
PyWavelets @ file:///Users/ec2-user/ci_py311/pywavelets_1678379192795/work
pyxnat==1.6
PyYAML==6.0.2
pyzmq @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_e6wiufh44w/croot/pyzmq_1686601381524/work
QDarkStyle @ file:///tmp/build/80754af9/qdarkstyle_1617386714626/work
qstylizer @ file:///Users/ec2-user/ci_py311/qstylizer_1678393978214/work/dist/qstylizer-0.2.2-py2.py3-none-any.whl
qt6-applications==6.4.3.2.3
qt6-tools==6.4.3.1.3
QtAwesome @ file:///Users/ec2-user/ci_py311/qtawesome_1678393953815/work
qtconsole @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_dexq2hi2gu/croot/qtconsole_1681394223590/work
QtPy @ file:///Users/ec2-user/ci_py311/qtpy_1678322936834/work
queuelib==1.5.0
RandomWords==0.4.0
rdflib==7.0.0
redis==5.2.0
referencing==0.36.2
regex @ file:///Users/ec2-user/ci_py311/regex_1678394018661/work
reportlab==4.0.6
requests==2.32.3
requests-file @ file:///Users/ktietz/demo/mc3/conda-bld/requests-file_1629455781986/work
requests-toolbelt==1.0.0
rfc3339-validator @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_07a1ken4gz/croot/rfc3339-validator_1683077050666/work
rfc3986-validator @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_6dzvsqx89i/croot/rfc3986-validator_1683059150431/work
rich==13.5.2
rlp==4.0.1
rope @ file:///Users/ec2-user/ci_py311/rope_1678379265159/work
rpds-py==0.25.1
rstream==0.30.0
Rtree @ file:///Users/ec2-user/ci_py311/rtree_1678394103092/work
ruamel-yaml-conda @ file:///Users/ec2-user/ci_py311/ruamel_yaml_1678394125333/work
ruamel.yaml @ file:///Users/ec2-user/ci_py311/ruamel.yaml_1678379291841/work
rumps==0.4.0
s3fs @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_3dy0qlp99f/croot/s3fs_1680018510125/work
s3transfer @ file:///Users/ec2-user/ci_py311/s3transfer_1678324574832/work
sacremoses @ file:///tmp/build/80754af9/sacremoses_1633107328213/work
scapy==2.5.0
scikit-image @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_3fh5dyitqb/croot/scikit-image_1682530834592/work
scikit-learn @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_506rr4lm7n/croot/scikit-learn_1684954727383/work
scipy==1.10.1
Scrapy @ file:///Users/ec2-user/ci_py311/scrapy_1678422467931/work
seaborn @ file:///Users/ec2-user/ci_py311/seaborn_1678394152964/work
selenium==4.18.1
selenium-wire==5.1.0
Send2Trash @ file:///tmp/build/80754af9/send2trash_1632406701022/work
service-identity @ file:///Users/ktietz/demo/mc3/conda-bld/service_identity_1629460757137/work
sh==1.14.3
simple-websocket==1.1.0
simplejson==3.19.2
sip @ file:///Users/ec2-user/ci_py311/sip_1678318421743/work
six @ file:///tmp/build/80754af9/six_1644875935023/work
smart-open @ file:///Users/ec2-user/ci_py311/smart_open_1678389689993/work
sniffio==1.3.0
snowballstemmer @ file:///tmp/build/80754af9/snowballstemmer_1637937080595/work
socksio==1.0.0
solders==0.25.0
sortedcontainers @ file:///tmp/build/80754af9/sortedcontainers_1623949099177/work
soupsieve==2.8
Sphinx @ file:///Users/ec2-user/ci_py311/sphinx_1678389735529/work
sphinxcontrib-applehelp @ file:///home/ktietz/src/ci/sphinxcontrib-applehelp_1611920841464/work
sphinxcontrib-devhelp @ file:///home/ktietz/src/ci/sphinxcontrib-devhelp_1611920923094/work
sphinxcontrib-htmlhelp @ file:///tmp/build/80754af9/sphinxcontrib-htmlhelp_1623945626792/work
sphinxcontrib-jsmath @ file:///home/ktietz/src/ci/sphinxcontrib-jsmath_1611920942228/work
sphinxcontrib-qthelp @ file:///home/ktietz/src/ci/sphinxcontrib-qthelp_1611921055322/work
sphinxcontrib-serializinghtml @ file:///tmp/build/80754af9/sphinxcontrib-serializinghtml_1624451540180/work
spyder @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_b93e0at0ak/croot/spyder_1681934083239/work
spyder-kernels @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_30ws3nleek/croot/spyder-kernels_1681307303955/work
SQLAlchemy @ file:///Users/ec2-user/ci_py311/sqlalchemy_1678379321154/work
stack-data @ file:///opt/conda/conda-bld/stack_data_1646927590127/work
starlette==0.27.0
statsmodels @ file:///Users/ec2-user/ci_py311/statsmodels_1678394299954/work
supervisor==4.2.5
svgwrite==1.4.3
sympy @ file:///Users/ec2-user/ci_py311_2/sympy_1679338337660/work
tables @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_ccbzs9wm7e/croot/pytables_1685123223946/work
tabulate @ file:///Users/ec2-user/ci_py311/tabulate_1678423547338/work
TBB==0.2
tblib @ file:///Users/ktietz/demo/mc3/conda-bld/tblib_1629402031467/work
tenacity==8.2.3
termcolor==2.5.0
terminado @ file:///Users/ec2-user/ci_py311/terminado_1678317735543/work
text-unidecode @ file:///Users/ktietz/demo/mc3/conda-bld/text-unidecode_1629401354553/work
textdistance @ file:///tmp/build/80754af9/textdistance_1612461398012/work
threadpoolctl @ file:///Users/ktietz/demo/mc3/conda-bld/threadpoolctl_1629802263681/work
three-merge @ file:///tmp/build/80754af9/three-merge_1607553261110/work
tifffile @ file:///tmp/build/80754af9/tifffile_1627275862826/work
time-machine==2.16.0
tinycss2 @ file:///Users/ec2-user/ci_py311/tinycss2_1678317366076/work
tinydb==4.8.2
tldextract==5.1.3
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
tomli @ file:///Users/ec2-user/ci_py311/tomli_1678315243316/work
tomlkit @ file:///Users/ec2-user/ci_py311/tomlkit_1678317388739/work
toolz @ file:///Users/ec2-user/ci_py311/toolz_1678323009669/work
torch==2.0.0
torchvision==0.15
tornado @ file:///Users/ec2-user/ci_py311/tornado_1678316833426/work
tqdm==4.67.1
traitlets @ file:///Users/ec2-user/ci_py311/traitlets_1678316097905/work
traits==6.3.2
transformers @ file:///tmp/build/80754af9/transformers_1633098115425/work
trio==0.24.0
trio-websocket==0.11.1
tushare==1.2.89
twikit==2.3.3
Twisted @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_3cf4rqmb9n/croot/twisted_1683796897214/work
typing-inspect==0.9.0
typing-inspection==0.4.1
typing-utils==0.1.0
typing_extensions==4.12.2
tzdata==2024.2
tzlocal==5.3.1
uc-micro-py @ file:///Users/ec2-user/ci_py311/uc-micro-py_1678394873457/work
ujson @ file:///Users/ec2-user/ci_py311/ujson_1678325349324/work
Unidecode @ file:///tmp/build/80754af9/unidecode_1614712377438/work
uri-template==1.3.0
urllib3==1.26.18
uvicorn==0.24.0
uvloop==0.17.0
vbuild==0.8.2
virtualenv==20.27.0
w3lib @ file:///Users/ktietz/demo/mc3/conda-bld/w3lib_1629359764703/work
watchdog @ file:///Users/ec2-user/ci_py311/watchdog_1678395046770/work
watchfiles==0.19.0
wcwidth @ file:///Users/ktietz/demo/mc3/conda-bld/wcwidth_1629357192024/work
web3==6.17.2
webcolors==24.11.1
webencodings==0.5.1
websocket-client==0.57.0
websockets==12.0
webvtt-py==0.5.1
Werkzeug @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_fegt3z60s3/croot/werkzeug_1679489762631/work
whatthepatch @ file:///Users/ec2-user/ci_py311/whatthepatch_1678379478749/work
widgetsnbextension @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_8feupjw2ld/croot/widgetsnbextension_1679313870305/work
wrapt @ file:///Users/ec2-user/ci_py311/wrapt_1678323111850/work
wsproto==1.2.0
wurlitzer @ file:///Users/ec2-user/ci_py311/wurlitzer_1678390004531/work
xarray @ file:///Users/ec2-user/ci_py311/xarray_1678395099624/work
XlsxWriter==3.1.2
xlwings @ file:///Users/ec2-user/ci_py311_2/xlwings_1679338568565/work
xyzservices @ file:///Users/ec2-user/ci_py311/xyzservices_1678325391212/work
y-py @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_7dvnlnkj12/croot/y-py_1683555629284/work
yapf @ file:///tmp/build/80754af9/yapf_1615749224965/work
yarl==1.18.3
you-get==0.4.1730
ypy-websocket @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_75t89iv95n/croot/ypy-websocket_1684171758794/work
zict @ file:///private/var/folders/sy/f16zz6x50xz3113nwtb9bvq00000gp/T/abs_59schmcson/croot/zict_1682698747213/work
zipp @ file:///Users/ec2-user/ci_py311/zipp_1678318061389/work
zope.interface @ file:///Users/ec2-user/ci_py311/zope.interface_1678379536727/work
zstandard @ file:///Users/ec2-user/ci_py311_2/zstandard_1679338593428/work

@ -1,289 +0,0 @@
[
{
"expression": "-ts_correlation(open, close, 20)",
"time_consuming": 21.09,
"formatted_time": "21.09秒",
"alpha_id": "/",
"status": "error",
"description": "Attempted to use inaccessible or unknown operator \"ts_correlation\"",
"simulation_timestamp": "2025-11-14 16:35:40",
"metrics": null
},
{
"expression": "ts_mean(volume / ts_mean(volume, 20), 30)",
"time_consuming": 90.94,
"formatted_time": "1分30.94秒",
"alpha_id": "akZ63dm1",
"status": "success",
"description": "/",
"simulation_timestamp": "2025-11-14 16:36:50",
"metrics": {
"id": "akZ63dm1",
"type": "REGULAR",
"author": "YC93384",
"settings": {
"instrumentType": "EQUITY",
"region": "USA",
"universe": "TOP3000",
"delay": 1,
"decay": 0,
"neutralization": "INDUSTRY",
"truncation": 0.08,
"pasteurization": "ON",
"unitHandling": "VERIFY",
"nanHandling": "OFF",
"maxTrade": "OFF",
"language": "FASTEXPR",
"visualization": false,
"startDate": "2018-01-20",
"endDate": "2023-01-20"
},
"regular": {
"code": "ts_mean(volume / ts_mean(volume, 20), 30)",
"description": null,
"operatorCount": 3
},
"dateCreated": "2025-11-14T03:36:48-05:00",
"dateSubmitted": null,
"dateModified": "2025-11-14T03:36:48-05:00",
"name": null,
"favorite": false,
"hidden": false,
"color": null,
"category": null,
"tags": [],
"classifications": [
{
"id": "DATA_USAGE:SINGLE_DATA_SET",
"name": "Single Data Set Alpha"
}
],
"grade": "INFERIOR",
"stage": "IS",
"status": "UNSUBMITTED",
"is": {
"pnl": 752501,
"bookSize": 20000000,
"longCount": 1462,
"shortCount": 1666,
"turnover": 0.1707,
"returns": 0.0152,
"drawdown": 0.1146,
"margin": 0.000178,
"sharpe": 0.25,
"fitness": 0.07,
"startDate": "2018-01-20",
"checks": [
{
"name": "LOW_SHARPE",
"result": "FAIL",
"limit": 1.25,
"value": 0.25
},
{
"name": "LOW_FITNESS",
"result": "FAIL",
"limit": 1.0,
"value": 0.07
},
{
"name": "LOW_TURNOVER",
"result": "PASS",
"limit": 0.01,
"value": 0.1707
},
{
"name": "HIGH_TURNOVER",
"result": "PASS",
"limit": 0.7,
"value": 0.1707
},
{
"name": "CONCENTRATED_WEIGHT",
"result": "PASS"
},
{
"name": "LOW_SUB_UNIVERSE_SHARPE",
"result": "PASS",
"limit": 0.11,
"value": 0.83
},
{
"name": "SELF_CORRELATION",
"result": "PENDING"
},
{
"name": "MATCHES_COMPETITION",
"result": "PASS",
"competitions": [
{
"id": "challenge",
"name": "Challenge"
}
]
}
]
},
"os": null,
"train": null,
"test": null,
"prod": null,
"competitions": null,
"themes": null,
"pyramids": null,
"pyramidThemes": null,
"team": null
}
},
{
"expression": "ts_rank((high - low) / (close - open + 0.001), 15)",
"time_consuming": 116.93,
"formatted_time": "1分56.93秒",
"alpha_id": "VkjVoGGb",
"status": "success",
"description": "/",
"simulation_timestamp": "2025-11-14 16:37:16",
"metrics": {
"id": "VkjVoGGb",
"type": "REGULAR",
"author": "YC93384",
"settings": {
"instrumentType": "EQUITY",
"region": "USA",
"universe": "TOP3000",
"delay": 1,
"decay": 0,
"neutralization": "INDUSTRY",
"truncation": 0.08,
"pasteurization": "ON",
"unitHandling": "VERIFY",
"nanHandling": "OFF",
"maxTrade": "OFF",
"language": "FASTEXPR",
"visualization": false,
"startDate": "2018-01-20",
"endDate": "2023-01-20"
},
"regular": {
"code": "ts_rank((high - low) / (close - open + 0.001), 15)",
"description": null,
"operatorCount": 5
},
"dateCreated": "2025-11-14T03:37:13-05:00",
"dateSubmitted": null,
"dateModified": "2025-11-14T03:37:14-05:00",
"name": null,
"favorite": false,
"hidden": false,
"color": null,
"category": null,
"tags": [],
"classifications": [
{
"id": "DATA_USAGE:SINGLE_DATA_SET",
"name": "Single Data Set Alpha"
}
],
"grade": "INFERIOR",
"stage": "IS",
"status": "UNSUBMITTED",
"is": {
"pnl": -1933631,
"bookSize": 20000000,
"longCount": 1562,
"shortCount": 1565,
"turnover": 1.3813,
"returns": -0.0391,
"drawdown": 0.2222,
"margin": -5.7e-05,
"sharpe": -1.15,
"fitness": -0.19,
"startDate": "2018-01-20",
"checks": [
{
"name": "LOW_SHARPE",
"result": "FAIL",
"limit": 1.25,
"value": -1.15
},
{
"name": "LOW_FITNESS",
"result": "FAIL",
"limit": 1.0,
"value": -0.19
},
{
"name": "LOW_TURNOVER",
"result": "PASS",
"limit": 0.01,
"value": 1.3813
},
{
"name": "HIGH_TURNOVER",
"result": "FAIL",
"limit": 0.7,
"value": 1.3813
},
{
"name": "CONCENTRATED_WEIGHT",
"result": "PASS"
},
{
"name": "LOW_SUB_UNIVERSE_SHARPE",
"result": "FAIL",
"limit": -0.5,
"value": -0.73
},
{
"name": "UNITS",
"result": "WARNING",
"message": "Incompatible unit for input of \"add\" at index 1, expected \"Unit[CSPrice:1]\", found \"Unit[]\""
},
{
"name": "SELF_CORRELATION",
"result": "PENDING"
},
{
"name": "MATCHES_COMPETITION",
"result": "PASS",
"competitions": [
{
"id": "challenge",
"name": "Challenge"
}
]
}
]
},
"os": null,
"train": null,
"test": null,
"prod": null,
"competitions": null,
"themes": null,
"pyramids": null,
"pyramidThemes": null,
"team": null
}
},
{
"expression": "-ts_rank(ts_skewness(returns(close), 10), 25)",
"time_consuming": 1.44,
"formatted_time": "1.44秒",
"alpha_id": "/",
"status": "error",
"description": "Attempted to use inaccessible or unknown operator \"ts_skewness\"",
"simulation_timestamp": "2025-11-14 16:37:22",
"metrics": null
},
{
"expression": "(close - ts_min(low, 50)) / (ts_max(high, 50) - ts_min(low, 50) + 0.001)",
"time_consuming": 5.76,
"formatted_time": "5.76秒",
"alpha_id": "/",
"status": "error",
"description": "Attempted to use inaccessible or unknown operator \"ts_min\"",
"simulation_timestamp": "2025-11-14 16:37:26",
"metrics": null
}
]

@ -1,524 +0,0 @@
[
{
"expression": "ts_rank(close - vwap, 12)",
"time_consuming": 15.79,
"formatted_time": "15.79秒",
"alpha_id": "/",
"status": "failed",
"description": "The read operation timed out",
"simulation_timestamp": "2025-11-14 16:58:48",
"metrics": null
},
{
"expression": "ts_mean((close - open) / (high - low + 0.001), 20)",
"time_consuming": 109.71,
"formatted_time": "1分49.71秒",
"alpha_id": "VkjVwxrG",
"status": "success",
"description": "/",
"simulation_timestamp": "2025-11-14 17:00:22",
"metrics": {
"id": "VkjVwxrG",
"type": "REGULAR",
"author": "YC93384",
"settings": {
"instrumentType": "EQUITY",
"region": "USA",
"universe": "TOP3000",
"delay": 1,
"decay": 0,
"neutralization": "INDUSTRY",
"truncation": 0.08,
"pasteurization": "ON",
"unitHandling": "VERIFY",
"nanHandling": "OFF",
"maxTrade": "OFF",
"language": "FASTEXPR",
"visualization": false,
"startDate": "2018-01-20",
"endDate": "2023-01-20"
},
"regular": {
"code": "ts_mean((close - open) / (high - low + 0.001), 20)",
"description": null,
"operatorCount": 5
},
"dateCreated": "2025-11-14T04:00:17-05:00",
"dateSubmitted": null,
"dateModified": "2025-11-14T04:00:18-05:00",
"name": null,
"favorite": false,
"hidden": false,
"color": null,
"category": null,
"tags": [],
"classifications": [
{
"id": "DATA_USAGE:SINGLE_DATA_SET",
"name": "Single Data Set Alpha"
}
],
"grade": "INFERIOR",
"stage": "IS",
"status": "UNSUBMITTED",
"is": {
"pnl": -4252305,
"bookSize": 20000000,
"longCount": 1570,
"shortCount": 1558,
"turnover": 0.3075,
"returns": -0.0859,
"drawdown": 0.5096,
"margin": -0.000559,
"sharpe": -0.83,
"fitness": -0.44,
"startDate": "2018-01-20",
"checks": [
{
"name": "LOW_SHARPE",
"result": "FAIL",
"limit": 1.25,
"value": -0.83
},
{
"name": "LOW_FITNESS",
"result": "FAIL",
"limit": 1.0,
"value": -0.44
},
{
"name": "LOW_TURNOVER",
"result": "PASS",
"limit": 0.01,
"value": 0.3075
},
{
"name": "HIGH_TURNOVER",
"result": "PASS",
"limit": 0.7,
"value": 0.3075
},
{
"name": "CONCENTRATED_WEIGHT",
"result": "PASS"
},
{
"name": "LOW_SUB_UNIVERSE_SHARPE",
"result": "FAIL",
"limit": -0.36,
"value": -0.7
},
{
"name": "UNITS",
"result": "WARNING",
"message": "Incompatible unit for input of \"add\" at index 1, expected \"Unit[CSPrice:1]\", found \"Unit[]\""
},
{
"name": "SELF_CORRELATION",
"result": "PENDING"
},
{
"name": "MATCHES_COMPETITION",
"result": "PASS",
"competitions": [
{
"id": "challenge",
"name": "Challenge"
}
]
}
]
},
"os": null,
"train": null,
"test": null,
"prod": null,
"competitions": null,
"themes": null,
"pyramids": null,
"pyramidThemes": null,
"team": null
}
},
{
"expression": "-ts_rank(ts_decay_linear(volume, 10), 30)",
"time_consuming": 124.43,
"formatted_time": "2分4.43秒",
"alpha_id": "E5W10mem",
"status": "success",
"description": "/",
"simulation_timestamp": "2025-11-14 17:00:37",
"metrics": {
"id": "E5W10mem",
"type": "REGULAR",
"author": "YC93384",
"settings": {
"instrumentType": "EQUITY",
"region": "USA",
"universe": "TOP3000",
"delay": 1,
"decay": 0,
"neutralization": "INDUSTRY",
"truncation": 0.08,
"pasteurization": "ON",
"unitHandling": "VERIFY",
"nanHandling": "OFF",
"maxTrade": "OFF",
"language": "FASTEXPR",
"visualization": false,
"startDate": "2018-01-20",
"endDate": "2023-01-20"
},
"regular": {
"code": "-ts_rank(ts_decay_linear(volume, 10), 30)",
"description": null,
"operatorCount": 3
},
"dateCreated": "2025-11-14T04:00:33-05:00",
"dateSubmitted": null,
"dateModified": "2025-11-14T04:00:34-05:00",
"name": null,
"favorite": false,
"hidden": false,
"color": null,
"category": null,
"tags": [],
"classifications": [
{
"id": "DATA_USAGE:SINGLE_DATA_SET",
"name": "Single Data Set Alpha"
}
],
"grade": "INFERIOR",
"stage": "IS",
"status": "UNSUBMITTED",
"is": {
"pnl": -1352690,
"bookSize": 20000000,
"longCount": 1610,
"shortCount": 1517,
"turnover": 0.3383,
"returns": -0.0273,
"drawdown": 0.2176,
"margin": -0.000162,
"sharpe": -0.58,
"fitness": -0.16,
"startDate": "2018-01-20",
"checks": [
{
"name": "LOW_SHARPE",
"result": "FAIL",
"limit": 1.25,
"value": -0.58
},
{
"name": "LOW_FITNESS",
"result": "FAIL",
"limit": 1.0,
"value": -0.16
},
{
"name": "LOW_TURNOVER",
"result": "PASS",
"limit": 0.01,
"value": 0.3383
},
{
"name": "HIGH_TURNOVER",
"result": "PASS",
"limit": 0.7,
"value": 0.3383
},
{
"name": "CONCENTRATED_WEIGHT",
"result": "PASS"
},
{
"name": "LOW_SUB_UNIVERSE_SHARPE",
"result": "FAIL",
"limit": -0.25,
"value": -0.66
},
{
"name": "SELF_CORRELATION",
"result": "PENDING"
},
{
"name": "MATCHES_COMPETITION",
"result": "PASS",
"competitions": [
{
"id": "challenge",
"name": "Challenge"
}
]
}
]
},
"os": null,
"train": null,
"test": null,
"prod": null,
"competitions": null,
"themes": null,
"pyramids": null,
"pyramidThemes": null,
"team": null
}
},
{
"expression": "ts_rank(adv20 - volume, 15) + ts_rank(volume, 15)",
"time_consuming": 85.26,
"formatted_time": "1分25.26秒",
"alpha_id": "0m3qkZN1",
"status": "success",
"description": "/",
"simulation_timestamp": "2025-11-14 17:02:08",
"metrics": {
"id": "0m3qkZN1",
"type": "REGULAR",
"author": "YC93384",
"settings": {
"instrumentType": "EQUITY",
"region": "USA",
"universe": "TOP3000",
"delay": 1,
"decay": 0,
"neutralization": "INDUSTRY",
"truncation": 0.08,
"pasteurization": "ON",
"unitHandling": "VERIFY",
"nanHandling": "OFF",
"maxTrade": "OFF",
"language": "FASTEXPR",
"visualization": false,
"startDate": "2018-01-20",
"endDate": "2023-01-20"
},
"regular": {
"code": "ts_rank(adv20 - volume, 15) + ts_rank(volume, 15)",
"description": null,
"operatorCount": 4
},
"dateCreated": "2025-11-14T04:02:06-05:00",
"dateSubmitted": null,
"dateModified": "2025-11-14T04:02:07-05:00",
"name": null,
"favorite": false,
"hidden": false,
"color": null,
"category": null,
"tags": [],
"classifications": [
{
"id": "DATA_USAGE:SINGLE_DATA_SET",
"name": "Single Data Set Alpha"
}
],
"grade": "INFERIOR",
"stage": "IS",
"status": "UNSUBMITTED",
"is": {
"pnl": 1607957,
"bookSize": 20000000,
"longCount": 1749,
"shortCount": 1375,
"turnover": 0.8699,
"returns": 0.0325,
"drawdown": 0.0811,
"margin": 7.5e-05,
"sharpe": 0.71,
"fitness": 0.14,
"startDate": "2018-01-20",
"checks": [
{
"name": "LOW_SHARPE",
"result": "FAIL",
"limit": 1.25,
"value": 0.71
},
{
"name": "LOW_FITNESS",
"result": "FAIL",
"limit": 1.0,
"value": 0.14
},
{
"name": "LOW_TURNOVER",
"result": "PASS",
"limit": 0.01,
"value": 0.8699
},
{
"name": "HIGH_TURNOVER",
"result": "FAIL",
"limit": 0.7,
"value": 0.8699
},
{
"name": "CONCENTRATED_WEIGHT",
"result": "PASS"
},
{
"name": "LOW_SUB_UNIVERSE_SHARPE",
"result": "PASS",
"limit": 0.31,
"value": 0.84
},
{
"name": "SELF_CORRELATION",
"result": "PENDING"
},
{
"name": "MATCHES_COMPETITION",
"result": "PASS",
"competitions": [
{
"id": "challenge",
"name": "Challenge"
}
]
}
]
},
"os": null,
"train": null,
"test": null,
"prod": null,
"competitions": null,
"themes": null,
"pyramids": null,
"pyramidThemes": null,
"team": null
}
},
{
"expression": "ts_mean(high - ts_delay(high, 1), 60) - ts_mean(low - ts_delay(low, 1), 60)",
"time_consuming": 86.01,
"formatted_time": "1分26.01秒",
"alpha_id": "wpxqw73d",
"status": "success",
"description": "/",
"simulation_timestamp": "2025-11-14 17:02:09",
"metrics": {
"id": "wpxqw73d",
"type": "REGULAR",
"author": "YC93384",
"settings": {
"instrumentType": "EQUITY",
"region": "USA",
"universe": "TOP3000",
"delay": 1,
"decay": 0,
"neutralization": "INDUSTRY",
"truncation": 0.08,
"pasteurization": "ON",
"unitHandling": "VERIFY",
"nanHandling": "OFF",
"maxTrade": "OFF",
"language": "FASTEXPR",
"visualization": false,
"startDate": "2018-01-20",
"endDate": "2023-01-20"
},
"regular": {
"code": "ts_mean(high - ts_delay(high, 1), 60) - ts_mean(low - ts_delay(low, 1), 60)",
"description": null,
"operatorCount": 7
},
"dateCreated": "2025-11-14T04:02:06-05:00",
"dateSubmitted": null,
"dateModified": "2025-11-14T04:02:06-05:00",
"name": null,
"favorite": false,
"hidden": false,
"color": null,
"category": null,
"tags": [],
"classifications": [
{
"id": "DATA_USAGE:SINGLE_DATA_SET",
"name": "Single Data Set Alpha"
}
],
"grade": "INFERIOR",
"stage": "IS",
"status": "UNSUBMITTED",
"is": {
"pnl": -1454336,
"bookSize": 20000000,
"longCount": 1602,
"shortCount": 1526,
"turnover": 1.0897,
"returns": -0.0294,
"drawdown": 0.5598,
"margin": -5.4e-05,
"sharpe": -0.19,
"fitness": -0.03,
"startDate": "2018-01-20",
"checks": [
{
"name": "LOW_SHARPE",
"result": "FAIL",
"limit": 1.25,
"value": -0.19
},
{
"name": "LOW_FITNESS",
"result": "FAIL",
"limit": 1.0,
"value": -0.03
},
{
"name": "LOW_TURNOVER",
"result": "PASS",
"limit": 0.01,
"value": 1.0897
},
{
"name": "HIGH_TURNOVER",
"result": "FAIL",
"limit": 0.7,
"value": 1.0897
},
{
"name": "CONCENTRATED_WEIGHT",
"result": "FAIL",
"date": "2022-10-27",
"limit": 0.1,
"value": 0.298634
},
{
"name": "LOW_SUB_UNIVERSE_SHARPE",
"result": "FAIL",
"limit": -0.08,
"value": -0.37
},
{
"name": "SELF_CORRELATION",
"result": "PENDING"
},
{
"name": "MATCHES_COMPETITION",
"result": "PASS",
"competitions": [
{
"id": "challenge",
"name": "Challenge"
}
]
}
]
},
"os": null,
"train": null,
"test": null,
"prod": null,
"competitions": null,
"themes": null,
"pyramids": null,
"pyramidThemes": null,
"team": null
}
}
]

@ -1,82 +0,0 @@
[
{
"expression": "ts_mean(close, 20) / ts_mean(close, 100) > 1.05 and ts_std(close / ts_mean(close, 10), 20) / ts_mean(close, 20) < 0.15",
"time_consuming": 5.94,
"formatted_time": "5.94秒",
"alpha_id": "/",
"status": "error",
"description": "Unexpected character 'a' near \"0) > 1.05 and ts_std\"",
"simulation_timestamp": "2025-11-14 17:35:28",
"metrics": null
},
{
"expression": "ts_min(low, 20) / ts_max(high, 60) > 0.8 and market_cap > ts_mean(market_cap, all)",
"time_consuming": 6.53,
"formatted_time": "6.53秒",
"alpha_id": "/",
"status": "error",
"description": "Unexpected character 'a' near \"60) > 0.8 and market\"",
"simulation_timestamp": "2025-11-14 17:35:29",
"metrics": null
},
{
"expression": "close > ts_mean(close, 50) and ts_delta(ts_rank(volume, 10), 5) > 0",
"time_consuming": 7.6,
"formatted_time": "7.60秒",
"alpha_id": "/",
"status": "error",
"description": "Unexpected character 'a' near \"lose, 50) and ts_del\"",
"simulation_timestamp": "2025-11-14 17:35:30",
"metrics": null
},
{
"expression": "ts_corr(close, vwap, 30) < 0.3 and ts_mean(volume, 5) / ts_mean(volume, 60) < 0.8",
"time_consuming": 5.8,
"formatted_time": "5.80秒",
"alpha_id": "/",
"status": "error",
"description": "Unexpected character 'a' near \"30) < 0.3 and ts_mea\"",
"simulation_timestamp": "2025-11-14 17:35:40",
"metrics": null
},
{
"expression": "abs(close - vwap) / vwap < 0.02 and volume < ts_mean(volume, 20)",
"time_consuming": 6.62,
"formatted_time": "6.62秒",
"alpha_id": "/",
"status": "error",
"description": "Unexpected character 'a' near \"ap < 0.02 and volume\"",
"simulation_timestamp": "2025-11-14 17:35:41",
"metrics": null
},
{
"expression": "(close - ts_mean(close, 30)) / ts_std(close, 30) > 1.5 and ts_delta(close, 5) < 0",
"time_consuming": 15.51,
"formatted_time": "15.51秒",
"alpha_id": "/",
"status": "error",
"description": "Unexpected character 'a' near \"30) > 1.5 and ts_del\"",
"simulation_timestamp": "2025-11-14 17:35:50",
"metrics": null
},
{
"expression": "ts_std(log(close / close[1]), 20) > ts_mean(ts_std(log(close / close[1]), 20), 60)",
"time_consuming": 1.2,
"formatted_time": "1.20秒",
"alpha_id": "/",
"status": "error",
"description": "Unexpected character '[' near \"se / close[1]), 20)\"",
"simulation_timestamp": "2025-11-14 17:35:56",
"metrics": null
},
{
"expression": "ts_range(high - low, 5) / ts_mean(high - low, 60) > 1.5 and ts_delta(ts_std(close, 10), 5) > 0",
"time_consuming": 7.38,
"formatted_time": "7.38秒",
"alpha_id": "/",
"status": "error",
"description": "Unexpected character 'a' near \"60) > 1.5 and ts_del\"",
"simulation_timestamp": "2025-11-14 17:36:02",
"metrics": null
}
]

@ -1,12 +0,0 @@
[
{
"expression": "ts_delta(ts_mean(close, 5), 10) / ts_std(close, 20) * (ts_mean(close, 20) / ts_mean(close, 100) > 1.02)",
"time_consuming": 6.62,
"formatted_time": "6.62秒",
"alpha_id": "/",
"status": "error",
"description": "Attempted to use inaccessible or unknown operator \"ts_std\"",
"simulation_timestamp": "2025-11-14 17:41:26",
"metrics": null
}
]

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
"""Alpha表达式服务"""
import time
import httpx
from typing import List, Dict, Any
from config.settings import settings
class AlphaService:
"""Alpha表达式服务类"""
def __init__(self, client: httpx.Client):
self.client = client
def simulate_alpha(self, expression: str) -> Dict[str, Any]:
"""模拟单个Alpha表达式"""
simulation_data = {
'type': 'REGULAR',
'settings': settings.SIMULATION_SETTINGS,
'regular': expression
}
sim_resp = self.client.post(f'{settings.BRAIN_API_URL}/simulations', json=simulation_data)
print(f"模拟提交状态: {sim_resp.status_code}")
if 'location' not in sim_resp.headers:
return {"status": "err", "message": "No location header in response"}
sim_progress_url = sim_resp.headers['location']
return self._wait_for_simulation_result(sim_progress_url)
def _wait_for_simulation_result(self, progress_url: str) -> Dict[str, Any]:
"""等待模拟结果"""
while True:
sim_progress_resp = self.client.get(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)
result_data = sim_progress_resp.json()
if result_data.get("status") == "ERROR":
error_message = result_data.get("message", "未知错误")
print(f"因子模拟失败: {error_message}")
return {"status": "err", "message": error_message}
alpha_id = result_data.get("alpha")
print(f"生成的Alpha ID: {alpha_id}")
return {"status": "ok", "alpha_id": alpha_id}

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
"""认证服务"""
import os
import httpx
from httpx import BasicAuth
from typing import Tuple, Dict, Any
from config.settings import settings
from models.entities import TokenInfo
class AuthService:
"""认证服务类"""
def __init__(self):
self.credentials_file = settings.credentials_file
def load_credentials(self) -> Tuple[str, str]:
"""加载凭证"""
if not os.path.exists(self.credentials_file):
self._create_credentials_file()
with open(self.credentials_file, 'r', encoding='utf-8') as f:
credentials = eval(f.read())
return credentials[0], credentials[1]
def _create_credentials_file(self) -> None:
"""创建凭证文件"""
print("未找到 account.txt 文件")
with open(self.credentials_file, 'w', encoding='utf-8') as f:
f.write("")
print("account.txt 文件已创建,请填写账号密码, 格式: ['username', 'password']")
exit(1)
def login(self, client: httpx.Client) -> TokenInfo:
"""登录并获取token"""
username, password = self.load_credentials()
# 设置 BasicAuth
client.auth = BasicAuth(username, password)
response = client.post(f'{settings.BRAIN_API_URL}/authentication')
print(f"登录状态: {response.status_code}")
if response.status_code == 201:
login_data = response.json()
print(f"登录成功!: {login_data}")
return TokenInfo(
token=login_data['token'],
expiry=int(login_data['token']['expiry'])
)
elif response.status_code == 429:
print("API rate limit exceeded")
exit(1)
else:
print(f"登录失败: {response.json()}")
raise Exception(f"登录失败: {response.json()}")

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
"""通知服务"""
import httpx
from datetime import datetime
from config.settings import settings
class NotificationService:
"""通知服务类"""
@staticmethod
def send_to_gotify(success_count: int, fail_count: int) -> None:
"""发送结果到Gotify"""
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
text = f"总计: 成功 {success_count} 个, 失败 {fail_count}\n\n完成时间: {now}"
title = f"alpha模拟结果 时间: {now}"
try:
resp = httpx.post(
settings.GOTIFY_URL,
json={'title': title, 'message': text},
timeout=10
)
print("通知发送成功")
except Exception as e:
print(f"通知发送失败: {e}")

@ -1,4 +0,0 @@
ts_mean((close - open) / (high - low + 0.001), 20)
-ts_rank(ts_decay_linear(volume, 10), 30)
ts_rank(adv20 - volume, 15) + ts_rank(volume, 15)
ts_mean(high - ts_delay(high, 1), 60) - ts_mean(low - ts_delay(low, 1), 60)

@ -1,9 +0,0 @@
# -*- coding: utf-8 -*-
"""
工具模块 - 包含各种工具函数
"""
from .file_utils import load_alpha_list, save_results_to_file
from .time_utils import format_time
__all__ = ['load_alpha_list', 'save_results_to_file', 'format_time']

@ -1,84 +0,0 @@
# -*- coding: utf-8 -*-
import os
import json
import time
from typing import List, Any
def load_alpha_list(file_path: str) -> List[str]:
"""从文件加载Alpha因子列表"""
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 save_results_to_file(results: List[Any], result_dir: str = 'result') -> str:
"""保存结果到文件"""
# 转换为可序列化的格式
serializable_results = []
for result in results:
if hasattr(result, '__dict__'):
# 如果是dataclass对象,转换为字典
result_dict = result.__dict__.copy()
else:
# 如果是字典
result_dict = result.copy()
# 处理时间消耗
if 'time_consuming' in result_dict:
result_dict['time_consuming'] = round(result_dict['time_consuming'], 2)
# 只需要确保所有浮点数精度一致
def round_floats(obj):
if isinstance(obj, float):
return round(obj, 6)
elif isinstance(obj, dict):
return {k: round_floats(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [round_floats(item) for item in obj]
else:
return obj
# 对结果中的所有浮点数进行精度处理
result_dict = round_floats(result_dict)
serializable_results.append(result_dict)
# 确保结果目录存在
if not os.path.exists(result_dir):
os.makedirs(result_dir)
result_name = f"{result_dir}/simulation_results-{str(int(time.time()))}.json"
with open(result_name, 'w', encoding='utf-8') as f:
json.dump(serializable_results, f, ensure_ascii=False, indent=2)
print(f"结果已保存到 {result_name}")
return result_name
def save_success_alpha(success_expression_list):
"""
将成功的表达式列表保存到 success.txt 文件中
如果文件不存在则创建如果存在则追加写入
"""
if not success_expression_list:
print("没有成功的表达式需要保存")
return
try:
with open('success.txt', 'a', encoding='utf-8') as f:
for expression in success_expression_list:
f.write(expression + '\n')
print(f"成功保存 {len(success_expression_list)} 个表达式到 success.txt")
except Exception as e:
print(f"保存文件时出错: {e}")

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
"""工具函数"""
import time
from typing import Callable, Any
def retry_on_exception(max_retries: int = 3, delay: float = 5.0) -> Callable:
"""异常重试装饰器"""
def decorator(func: Callable) -> Callable:
def wrapper(*args, **kwargs) -> Any:
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_retries - 1:
raise e
print(f"尝试 {attempt + 1}/{max_retries} 失败: {e}")
print(f"{delay}秒后重试...")
time.sleep(delay)
return None
return wrapper
return decorator

@ -1,9 +0,0 @@
# -*- coding: utf-8 -*-
def format_time(seconds: float) -> str:
"""将秒数格式化为 xx分xx秒 格式"""
if seconds < 60:
return f"{seconds:.2f}"
else:
minutes = int(seconds // 60)
remaining_seconds = seconds % 60
return f"{minutes}{remaining_seconds:.2f}"
Loading…
Cancel
Save