parent
0b84cb8222
commit
d4e55e9aca
@ -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…
Reference in new issue