parent
168298ace4
commit
83bac3cf78
@ -1,5 +1 @@ |
|||||||
ts_rank(ts_returns(close, 15), 30) |
ts_delta(ts_mean(close, 5), 10) / ts_std(close, 20) * (ts_mean(close, 20) / ts_mean(close, 100) > 1.02) |
||||||
-ts_corr(ts_rank(close, 30), ts_rank(volume, 30), 10) |
|
||||||
(close - ts_min(close, 20)) / (ts_max(close, 20) - ts_min(close, 20)) |
|
||||||
ts_rank(ts_delta(close, 3) / ts_delay(close, 3), 15) |
|
||||||
-ts_std(ts_returns(close, 1), 30) |
|
||||||
@ -1,496 +0,0 @@ |
|||||||
import os.path |
|
||||||
import httpx |
|
||||||
import json |
|
||||||
from httpx import BasicAuth |
|
||||||
import time |
|
||||||
from random import uniform |
|
||||||
import threading |
|
||||||
from concurrent.futures import ThreadPoolExecutor, as_completed |
|
||||||
|
|
||||||
|
|
||||||
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): |
|
||||||
if not os.path.exists(self.credentials_file): |
|
||||||
print("未找到 account.txt 文件") |
|
||||||
with open(self.credentials_file, 'w') as f: f.write("") |
|
||||||
print("account.txt 文件已创建,请填写账号密码, 格式: ['username', 'password]") |
|
||||||
exit(1) |
|
||||||
|
|
||||||
with open(self.credentials_file) as f: |
|
||||||
credentials = eval(f.read()) |
|
||||||
return credentials[0], credentials[1] |
|
||||||
|
|
||||||
"""登录认证""" |
|
||||||
def login(self): |
|
||||||
username, password = self.load_credentials() |
|
||||||
self.client = httpx.Client(auth=BasicAuth(username, password)) |
|
||||||
|
|
||||||
response = self.client.post(f'{self.brain_api_url}/authentication') |
|
||||||
print(f"登录状态: {response.status_code}") |
|
||||||
|
|
||||||
if response.status_code == 201: |
|
||||||
print("登录成功!") |
|
||||||
return True |
|
||||||
else: |
|
||||||
print(f"登录失败: {response.json()}") |
|
||||||
return False |
|
||||||
|
|
||||||
"""模拟Alpha因子""" |
|
||||||
def simulate_alpha(self, expression, settings=None): |
|
||||||
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 |
|
||||||
print(sim_progress_resp.json()) |
|
||||||
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): |
|
||||||
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() |
|
||||||
return self._parse_alpha_metrics(alpha_data) |
|
||||||
else: |
|
||||||
return {"error": f"无法获取Alpha信息: {alpha_resp.status_code}"} |
|
||||||
|
|
||||||
except Exception as e: |
|
||||||
return {"error": f"获取指标时出错: {str(e)}"} |
|
||||||
|
|
||||||
"""解析Alpha数据,提取关键指标""" |
|
||||||
def _parse_alpha_metrics(self, alpha_data): |
|
||||||
metrics = {} |
|
||||||
|
|
||||||
try: |
|
||||||
# 从train字段获取指标数据 |
|
||||||
if 'train' in alpha_data and alpha_data['train']: |
|
||||||
train_data = alpha_data['train'] |
|
||||||
metrics.update({ |
|
||||||
'sharpe_ratio': train_data.get('sharpe', None), |
|
||||||
'annual_return': train_data.get('returns', None), |
|
||||||
'max_drawdown': train_data.get('drawdown', None), |
|
||||||
'turnover': train_data.get('turnover', None), |
|
||||||
'fitness': train_data.get('fitness', None), |
|
||||||
'pnl': train_data.get('pnl', None), |
|
||||||
'book_size': train_data.get('bookSize', None), |
|
||||||
'long_count': train_data.get('longCount', None), |
|
||||||
'short_count': train_data.get('shortCount', None), |
|
||||||
'margin': train_data.get('margin', None), |
|
||||||
'start_date': train_data.get('startDate', None), |
|
||||||
}) |
|
||||||
|
|
||||||
# 从is字段获取样本内测试数据 |
|
||||||
if 'is' in alpha_data and alpha_data['is']: |
|
||||||
is_data = alpha_data['is'] |
|
||||||
metrics.update({ |
|
||||||
'is_sharpe': is_data.get('sharpe', None), |
|
||||||
'is_returns': is_data.get('returns', None), |
|
||||||
'is_drawdown': is_data.get('drawdown', None), |
|
||||||
'is_turnover': is_data.get('turnover', None), |
|
||||||
'is_fitness': is_data.get('fitness', None), |
|
||||||
'is_pnl': is_data.get('pnl', None), |
|
||||||
}) |
|
||||||
|
|
||||||
# 从test字段获取样本外测试数据 |
|
||||||
if 'test' in alpha_data and alpha_data['test']: |
|
||||||
test_data = alpha_data['test'] |
|
||||||
metrics.update({ |
|
||||||
'test_sharpe': test_data.get('sharpe', None), |
|
||||||
'test_returns': test_data.get('returns', None), |
|
||||||
'test_drawdown': test_data.get('drawdown', None), |
|
||||||
'test_turnover': test_data.get('turnover', None), |
|
||||||
'test_fitness': test_data.get('fitness', None), |
|
||||||
'test_pnl': test_data.get('pnl', None), |
|
||||||
}) |
|
||||||
|
|
||||||
# 其他重要信息 |
|
||||||
metrics.update({ |
|
||||||
'alpha_id': alpha_data.get('id', None), |
|
||||||
'grade': alpha_data.get('grade', None), |
|
||||||
'stage': alpha_data.get('stage', None), |
|
||||||
'status': alpha_data.get('status', None), |
|
||||||
'date_created': alpha_data.get('dateCreated', None), |
|
||||||
}) |
|
||||||
|
|
||||||
# 解析检查结果 |
|
||||||
if 'is' in alpha_data and 'checks' in alpha_data['is']: |
|
||||||
checks = alpha_data['is']['checks'] |
|
||||||
check_results = {} |
|
||||||
for check in checks: |
|
||||||
check_name = check.get('name', '') |
|
||||||
result = check.get('result', '') |
|
||||||
value = check.get('value', None) |
|
||||||
check_results[check_name.lower()] = { |
|
||||||
'result': result, |
|
||||||
'value': value, |
|
||||||
'limit': check.get('limit', None) |
|
||||||
} |
|
||||||
metrics['checks'] = check_results |
|
||||||
|
|
||||||
except Exception as e: |
|
||||||
metrics['error'] = f"解析指标时出错: {str(e)}" |
|
||||||
|
|
||||||
return metrics |
|
||||||
|
|
||||||
def close(self): |
|
||||||
"""关闭连接""" |
|
||||||
if self.client: |
|
||||||
self.client.close() |
|
||||||
|
|
||||||
|
|
||||||
class AlphaSimulationManager: |
|
||||||
def __init__(self, credentials_file='account.txt'): |
|
||||||
self.credentials_file = credentials_file |
|
||||||
self.results = [] |
|
||||||
|
|
||||||
"""将秒数格式化为 xx分xx秒 格式""" |
|
||||||
def format_time(self, seconds): |
|
||||||
if seconds < 60: |
|
||||||
return f"{seconds:.2f}秒" |
|
||||||
else: |
|
||||||
minutes = int(seconds // 60) |
|
||||||
remaining_seconds = seconds % 60 |
|
||||||
return f"{minutes}分{remaining_seconds:.2f}秒" |
|
||||||
|
|
||||||
"""模拟单个Alpha因子(线程安全)""" |
|
||||||
def simulate_single_alpha(self, api, expression, settings=None): |
|
||||||
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": |
|
||||||
# 模拟成功的结果 |
|
||||||
result = { |
|
||||||
"expression": expression, |
|
||||||
"time_consuming": time_consuming, |
|
||||||
"formatted_time": self.format_time(time_consuming), |
|
||||||
"alpha_id": simulation_result["alpha_id"], |
|
||||||
"status": "success", |
|
||||||
"description": "/", |
|
||||||
"simulation_timestamp": time.strftime("%Y-%m-%d %H:%M:%S"), |
|
||||||
# 训练集指标 |
|
||||||
"train_metrics": { |
|
||||||
"sharpe_ratio": simulation_result["metrics"].get('sharpe_ratio'), |
|
||||||
"annual_return": simulation_result["metrics"].get('annual_return'), |
|
||||||
"max_drawdown": simulation_result["metrics"].get('max_drawdown'), |
|
||||||
"turnover": simulation_result["metrics"].get('turnover'), |
|
||||||
"fitness": simulation_result["metrics"].get('fitness'), |
|
||||||
"pnl": simulation_result["metrics"].get('pnl'), |
|
||||||
"book_size": simulation_result["metrics"].get('book_size'), |
|
||||||
"long_count": simulation_result["metrics"].get('long_count'), |
|
||||||
"short_count": simulation_result["metrics"].get('short_count'), |
|
||||||
"margin": simulation_result["metrics"].get('margin'), |
|
||||||
}, |
|
||||||
# 样本内测试指标 |
|
||||||
"is_metrics": { |
|
||||||
"sharpe_ratio": simulation_result["metrics"].get('is_sharpe'), |
|
||||||
"annual_return": simulation_result["metrics"].get('is_returns'), |
|
||||||
"max_drawdown": simulation_result["metrics"].get('is_drawdown'), |
|
||||||
"turnover": simulation_result["metrics"].get('is_turnover'), |
|
||||||
"fitness": simulation_result["metrics"].get('is_fitness'), |
|
||||||
"pnl": simulation_result["metrics"].get('is_pnl'), |
|
||||||
}, |
|
||||||
# 样本外测试指标 |
|
||||||
"test_metrics": { |
|
||||||
"sharpe_ratio": simulation_result["metrics"].get('test_sharpe'), |
|
||||||
"annual_return": simulation_result["metrics"].get('test_returns'), |
|
||||||
"max_drawdown": simulation_result["metrics"].get('test_drawdown'), |
|
||||||
"turnover": simulation_result["metrics"].get('test_turnover'), |
|
||||||
"fitness": simulation_result["metrics"].get('test_fitness'), |
|
||||||
"pnl": simulation_result["metrics"].get('test_pnl'), |
|
||||||
}, |
|
||||||
# 其他信息 |
|
||||||
"alpha_info": { |
|
||||||
"grade": simulation_result["metrics"].get('grade'), |
|
||||||
"stage": simulation_result["metrics"].get('stage'), |
|
||||||
"status": simulation_result["metrics"].get('status'), |
|
||||||
"date_created": simulation_result["metrics"].get('date_created'), |
|
||||||
"checks": simulation_result["metrics"].get('checks', {}) |
|
||||||
} |
|
||||||
} |
|
||||||
print(f"✓ 因子模拟成功: {expression}") |
|
||||||
print(f" 耗时: {self.format_time(time_consuming)},Alpha ID: {simulation_result['alpha_id']}") |
|
||||||
|
|
||||||
# 打印关键指标 |
|
||||||
self._print_success_metrics(simulation_result["metrics"]) |
|
||||||
|
|
||||||
else: |
|
||||||
# 模拟失败的结果(API返回的错误) |
|
||||||
result = { |
|
||||||
"expression": expression, |
|
||||||
"time_consuming": time_consuming, |
|
||||||
"formatted_time": self.format_time(time_consuming), |
|
||||||
"alpha_id": "/", |
|
||||||
"status": "error", |
|
||||||
"description": simulation_result["message"], |
|
||||||
"simulation_timestamp": time.strftime("%Y-%m-%d %H:%M:%S"), |
|
||||||
"performance_metrics": {}, |
|
||||||
"risk_metrics": {}, |
|
||||||
"quantile_metrics": {}, |
|
||||||
"other_metrics": {} |
|
||||||
} |
|
||||||
print(f"✗ 因子模拟失败: {expression}") |
|
||||||
print(f" 耗时: {self.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 = { |
|
||||||
"expression": expression, |
|
||||||
"time_consuming": time_consuming, |
|
||||||
"formatted_time": self.format_time(time_consuming), |
|
||||||
"alpha_id": "/", |
|
||||||
"status": "failed", |
|
||||||
"description": str(e), |
|
||||||
"simulation_timestamp": time.strftime("%Y-%m-%d %H:%M:%S"), |
|
||||||
"performance_metrics": {}, |
|
||||||
"risk_metrics": {}, |
|
||||||
"quantile_metrics": {}, |
|
||||||
"other_metrics": {} |
|
||||||
} |
|
||||||
print(f"✗ 因子模拟异常: {expression}") |
|
||||||
print(f" 耗时: {self.format_time(time_consuming)},异常: {str(e)}") |
|
||||||
|
|
||||||
return result |
|
||||||
|
|
||||||
"""打印成功因子的关键指标""" |
|
||||||
|
|
||||||
def _print_success_metrics(self, metrics): |
|
||||||
if 'error' in metrics: |
|
||||||
print(f" 指标获取错误: {metrics['error']}") |
|
||||||
return |
|
||||||
|
|
||||||
print(" 关键指标 (训练集):") |
|
||||||
key_metrics = [ |
|
||||||
('夏普比率', 'sharpe_ratio'), |
|
||||||
('年化收益', 'annual_return'), |
|
||||||
('最大回撤', 'max_drawdown'), |
|
||||||
('换手率', 'turnover'), |
|
||||||
('适应度', 'fitness'), |
|
||||||
('PNL', 'pnl'), |
|
||||||
] |
|
||||||
|
|
||||||
for chinese_name, metric_key in key_metrics: |
|
||||||
value = metrics.get(metric_key) |
|
||||||
if value is not None: |
|
||||||
if isinstance(value, float): |
|
||||||
value = f"{value:.4f}" |
|
||||||
print(f" {chinese_name}: {value}") |
|
||||||
|
|
||||||
# 显示样本外测试的夏普比率(如果存在) |
|
||||||
test_sharpe = metrics.get('test_sharpe') |
|
||||||
if test_sharpe is not None: |
|
||||||
print(f" 样本外夏普比率: {test_sharpe:.4f}") |
|
||||||
|
|
||||||
"""模拟一批Alpha因子(3个一组)""" |
|
||||||
def simulate_alpha_batch(self, alpha_batch, batch_number): |
|
||||||
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"本批总耗时: {self.format_time(batch_total_time)}") |
|
||||||
print(f"{'=' * 60}") |
|
||||||
|
|
||||||
return batch_results |
|
||||||
|
|
||||||
"""运行批量模拟""" |
|
||||||
def run_simulation(self, alpha_list, batch_size=3): |
|
||||||
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) |
|
||||||
|
|
||||||
# 保存结果到文件 |
|
||||||
self.save_results(all_results) |
|
||||||
|
|
||||||
return all_results |
|
||||||
|
|
||||||
"""打印结果汇总""" |
|
||||||
def print_summary(self, results, total_time): |
|
||||||
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"总耗时: {self.format_time(total_time)}") |
|
||||||
print(f"{'=' * 60}") |
|
||||||
|
|
||||||
for i, result in enumerate(results, 1): |
|
||||||
status_icon = "✓" if result['status'] == 'success' else "✗" |
|
||||||
print(f"{i}. {status_icon} {result['expression']}") |
|
||||||
print(f" 状态: {result['status']}") |
|
||||||
print(f" 耗时: {result['formatted_time']}") |
|
||||||
print(f" Alpha ID: {result['alpha_id']}") |
|
||||||
if result['status'] != 'success': |
|
||||||
print(f" 原因: {result['description']}") |
|
||||||
print() |
|
||||||
|
|
||||||
"""保存结果到文件""" |
|
||||||
def save_results(self, results): |
|
||||||
# 转换为可序列化的格式 |
|
||||||
serializable_results = [] |
|
||||||
for result in results: |
|
||||||
serializable_result = result.copy() |
|
||||||
serializable_result['time_consuming'] = round(serializable_result['time_consuming'], 2) |
|
||||||
|
|
||||||
# 处理metrics中的浮点数,保留6位小数 |
|
||||||
for metric_category in ['performance_metrics', 'risk_metrics', 'quantile_metrics', 'other_metrics']: |
|
||||||
if metric_category in serializable_result: |
|
||||||
for key, value in serializable_result[metric_category].items(): |
|
||||||
if isinstance(value, float): |
|
||||||
serializable_result[metric_category][key] = round(value, 6) |
|
||||||
|
|
||||||
serializable_results.append(serializable_result) |
|
||||||
|
|
||||||
# 将日志文件, 保存到当前目录下, result 文件夹中 |
|
||||||
if not os.path.exists('./result'): |
|
||||||
os.makedirs('./result') |
|
||||||
|
|
||||||
result_name = f"result/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}") |
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
# 待模拟因子列表 |
|
||||||
with open('alpha.txt', 'r', encoding='utf-8') as file: |
|
||||||
alpha_list = [line.strip() for line in file] |
|
||||||
|
|
||||||
if not alpha_list: |
|
||||||
print("alpha.txt 文件不存在") |
|
||||||
with open('alpha.txt', 'w', encoding='utf-8') as file: file.write("") |
|
||||||
print("已创建 alpha.txt 文件, 请添加因子后重新运行, 一行一个因子") |
|
||||||
exit(1) |
|
||||||
|
|
||||||
# 创建模拟管理器并运行 |
|
||||||
manager = AlphaSimulationManager() |
|
||||||
results = manager.run_simulation(alpha_list, batch_size=3) |
|
||||||
@ -1,139 +0,0 @@ |
|||||||
[ |
|
||||||
{ |
|
||||||
"expression": "ts_rank(ts_returns(close, 15), 30)", |
|
||||||
"time_consuming": 5.89, |
|
||||||
"formatted_time": "5.89秒", |
|
||||||
"alpha_id": "/", |
|
||||||
"status": "error", |
|
||||||
"description": "Attempted to use inaccessible or unknown operator \"ts_returns\"", |
|
||||||
"simulation_timestamp": "2025-11-13 23:30:43", |
|
||||||
"train_metrics": null, |
|
||||||
"is_metrics": null, |
|
||||||
"test_metrics": null, |
|
||||||
"alpha_info": null |
|
||||||
}, |
|
||||||
{ |
|
||||||
"expression": "(close - ts_min(close, 20)) / (ts_max(close, 20) - ts_min(close, 20))", |
|
||||||
"time_consuming": 7.89, |
|
||||||
"formatted_time": "7.89秒", |
|
||||||
"alpha_id": "/", |
|
||||||
"status": "error", |
|
||||||
"description": "Attempted to use inaccessible or unknown operator \"ts_min\"", |
|
||||||
"simulation_timestamp": "2025-11-13 23:30:45", |
|
||||||
"train_metrics": null, |
|
||||||
"is_metrics": null, |
|
||||||
"test_metrics": null, |
|
||||||
"alpha_info": null |
|
||||||
}, |
|
||||||
{ |
|
||||||
"expression": "-ts_corr(ts_rank(close, 30), ts_rank(volume, 30), 10)", |
|
||||||
"time_consuming": 88.99, |
|
||||||
"formatted_time": "1分28.99秒", |
|
||||||
"alpha_id": "JjEVlkNx", |
|
||||||
"status": "success", |
|
||||||
"description": "/", |
|
||||||
"simulation_timestamp": "2025-11-13 23:32:06", |
|
||||||
"train_metrics": { |
|
||||||
"sharpe_ratio": null, |
|
||||||
"annual_return": null, |
|
||||||
"max_drawdown": null, |
|
||||||
"turnover": null, |
|
||||||
"fitness": null, |
|
||||||
"pnl": null, |
|
||||||
"book_size": null, |
|
||||||
"long_count": null, |
|
||||||
"short_count": null, |
|
||||||
"margin": null |
|
||||||
}, |
|
||||||
"is_metrics": { |
|
||||||
"sharpe_ratio": 1.15, |
|
||||||
"annual_return": 0.0604, |
|
||||||
"max_drawdown": 0.1311, |
|
||||||
"turnover": 0.4517, |
|
||||||
"fitness": 0.42, |
|
||||||
"pnl": 2988907 |
|
||||||
}, |
|
||||||
"test_metrics": { |
|
||||||
"sharpe_ratio": null, |
|
||||||
"annual_return": null, |
|
||||||
"max_drawdown": null, |
|
||||||
"turnover": null, |
|
||||||
"fitness": null, |
|
||||||
"pnl": null |
|
||||||
}, |
|
||||||
"alpha_info": { |
|
||||||
"grade": "INFERIOR", |
|
||||||
"stage": "IS", |
|
||||||
"status": "UNSUBMITTED", |
|
||||||
"date_created": "2025-11-13T10:32:05-05:00", |
|
||||||
"checks": { |
|
||||||
"low_sharpe": { |
|
||||||
"result": "FAIL", |
|
||||||
"value": 1.15, |
|
||||||
"limit": 1.25 |
|
||||||
}, |
|
||||||
"low_fitness": { |
|
||||||
"result": "FAIL", |
|
||||||
"value": 0.42, |
|
||||||
"limit": 1.0 |
|
||||||
}, |
|
||||||
"low_turnover": { |
|
||||||
"result": "PASS", |
|
||||||
"value": 0.4517, |
|
||||||
"limit": 0.01 |
|
||||||
}, |
|
||||||
"high_turnover": { |
|
||||||
"result": "PASS", |
|
||||||
"value": 0.4517, |
|
||||||
"limit": 0.7 |
|
||||||
}, |
|
||||||
"concentrated_weight": { |
|
||||||
"result": "PASS", |
|
||||||
"value": null, |
|
||||||
"limit": null |
|
||||||
}, |
|
||||||
"low_sub_universe_sharpe": { |
|
||||||
"result": "PASS", |
|
||||||
"value": 0.76, |
|
||||||
"limit": 0.5 |
|
||||||
}, |
|
||||||
"self_correlation": { |
|
||||||
"result": "PENDING", |
|
||||||
"value": null, |
|
||||||
"limit": null |
|
||||||
}, |
|
||||||
"matches_competition": { |
|
||||||
"result": "PASS", |
|
||||||
"value": null, |
|
||||||
"limit": null |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"expression": "-ts_std(ts_returns(close, 1), 30)", |
|
||||||
"time_consuming": 1.42, |
|
||||||
"formatted_time": "1.42秒", |
|
||||||
"alpha_id": "/", |
|
||||||
"status": "error", |
|
||||||
"description": "Attempted to use inaccessible or unknown operator \"ts_std\"", |
|
||||||
"simulation_timestamp": "2025-11-13 23:32:15", |
|
||||||
"train_metrics": null, |
|
||||||
"is_metrics": null, |
|
||||||
"test_metrics": null, |
|
||||||
"alpha_info": null |
|
||||||
}, |
|
||||||
{ |
|
||||||
"expression": "ts_rank(ts_delta(close, 3) / ts_delay(close, 3), 15)", |
|
||||||
"time_consuming": 148.04, |
|
||||||
"formatted_time": "2分28.04秒", |
|
||||||
"alpha_id": "/", |
|
||||||
"status": "failed", |
|
||||||
"description": "_ssl.c:980: The handshake operation timed out", |
|
||||||
"simulation_timestamp": "2025-11-13 23:34:42", |
|
||||||
"train_metrics": null, |
|
||||||
"is_metrics": null, |
|
||||||
"test_metrics": null, |
|
||||||
"alpha_info": null |
|
||||||
} |
|
||||||
] |
|
||||||
@ -0,0 +1,289 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"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 |
||||||
|
} |
||||||
|
] |
||||||
@ -0,0 +1,524 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"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 |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
@ -0,0 +1,82 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"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 |
||||||
|
} |
||||||
|
] |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"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,4 @@ |
|||||||
|
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) |
||||||
Loading…
Reference in new issue