main
Jack 6 months ago
parent d81f00ab85
commit 2bccfa5087
  1. 2
      wqb-simulate/alpha.txt
  2. 24
      wqb-simulate/result/simulation_results-1763042291.json
  3. 41
      wqb-simulate/result/simulation_results-1763042641.json
  4. 41
      wqb-simulate/result/simulation_results-1763042892.json
  5. 187
      wqb-simulate/simulate.py

@ -1 +1 @@
ts_Mean(ts_mean(close - delay(close,1),5) / atr(15), 30)
rank(ts_sum(vec_avg(nws12_afterhsz_sl), 60)) * 0.7 + rank(-ts_delta(close, 2)) * 0.3

@ -0,0 +1,24 @@
{
"simulation_info": {
"total_count": 1,
"success_count": 0,
"failed_count": 1,
"completion_time": "2025-11-13 21:58:11",
"total_time_seconds": 10.505059003829956
},
"results": [
{
"expression": "ts_mean(ts_mean(close - delay(close,1),5) / atr(15), 30)",
"time_consuming_seconds": 10.505059003829956,
"formatted_time": "10.51秒",
"alpha_id": "/",
"status": "failed",
"description": "'alpha'",
"simulation_timestamp": "2025-11-13 21:58:11",
"performance_metrics": {},
"risk_metrics": {},
"quantile_metrics": {},
"other_metrics": {}
}
]
}

@ -0,0 +1,41 @@
[
{
"expression": "rank(ts_sum(vec_avg(nws12_afterhsz_sl), 60)) * 0.7 + rank(-ts_delta(close, 2)) * 0.3",
"time_consuming": 75.8,
"formatted_time": "1分15.80秒",
"alpha_id": "WjqvZQLO",
"status": "success",
"description": "/",
"simulation_timestamp": "2025-11-13 22:04:01",
"performance_metrics": {
"sharpe_ratio": null,
"annual_return": null,
"annual_volatility": null,
"max_drawdown": null,
"information_ratio": null,
"total_return": null
},
"risk_metrics": {
"turnover": null,
"score": null,
"specific_return": null,
"specific_risk": null,
"tail_ratio": null,
"common_ratio": null
},
"quantile_metrics": {
"top_minus_bottom": null,
"top_decile_return": null,
"bottom_decile_return": null,
"ic": null,
"ic_decay": null
},
"other_metrics": {
"capacity": null,
"fitness": null,
"instrument_count": null,
"start_date": null,
"end_date": null
}
}
]

@ -0,0 +1,41 @@
[
{
"expression": "rank(ts_sum(vec_avg(nws12_afterhsz_sl), 60)) * 0.7 + rank(-ts_delta(close, 2)) * 0.3",
"time_consuming": 78.3,
"formatted_time": "1分18.30秒",
"alpha_id": "WjqvZQLO",
"status": "success",
"description": "/",
"simulation_timestamp": "2025-11-13 22:08:12",
"performance_metrics": {
"sharpe_ratio": null,
"annual_return": null,
"annual_volatility": null,
"max_drawdown": null,
"information_ratio": null,
"total_return": null
},
"risk_metrics": {
"turnover": null,
"score": null,
"specific_return": null,
"specific_risk": null,
"tail_ratio": null,
"common_ratio": null
},
"quantile_metrics": {
"top_minus_bottom": null,
"top_decile_return": null,
"bottom_decile_return": null,
"ic": null,
"ic_decay": null
},
"other_metrics": {
"capacity": null,
"fitness": null,
"instrument_count": null,
"start_date": null,
"end_date": null
}
}
]

@ -1,5 +1,4 @@
import os.path
import httpx
import json
from httpx import BasicAuth
@ -15,8 +14,8 @@ class WorldQuantBrainSimulate:
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("")
@ -27,8 +26,8 @@ class WorldQuantBrainSimulate:
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))
@ -42,8 +41,8 @@ class WorldQuantBrainSimulate:
print(f"登录失败: {response.json()}")
return False
"""模拟Alpha因子"""
def simulate_alpha(self, expression, settings=None):
"""模拟Alpha因子"""
if self.client is None:
raise Exception("请先登录")
@ -94,9 +93,87 @@ class WorldQuantBrainSimulate:
# 返回一个特殊标识,表示模拟失败
return {"status": "error", "message": result}
result = sim_progress_resp.json()["alpha"]
print(f"生成的Alpha ID: {result}")
return {"status": "success", "alpha_id": 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 == 200:
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:
# 基本统计信息
if 'returns' in alpha_data:
returns = alpha_data['returns']
metrics.update({
'sharpe_ratio': returns.get('sharpe', None),
'annual_return': returns.get('annualReturn', None),
'annual_volatility': returns.get('annualVolatility', None),
'max_drawdown': returns.get('maxDrawdown', None),
'information_ratio': returns.get('informationRatio', None),
'tail_ratio': returns.get('tailRatio', None),
'common_ratio': returns.get('commonRatio', None),
})
# 风险调整后收益
if 'riskAdjustment' in alpha_data:
risk_adj = alpha_data['riskAdjustment']
metrics.update({
'risk_adjusted_return': risk_adj.get('return', None),
'turnover': risk_adj.get('turnover', None),
'score': risk_adj.get('score', None),
'specific_return': risk_adj.get('specificReturn', None),
'specific_risk': risk_adj.get('specificRisk', None),
})
# 分位数表现
if 'quantiles' in alpha_data:
quantiles = alpha_data['quantiles']
metrics.update({
'top_minus_bottom': quantiles.get('topMinusBottom', None),
'top_decile_return': quantiles.get('topDecileReturn', None),
'bottom_decile_return': quantiles.get('bottomDecileReturn', None),
'ic': quantiles.get('ic', None),
'ic_decay': quantiles.get('icDecay', None),
})
# 其他重要指标
metrics.update({
'total_return': alpha_data.get('totalReturn', None),
'capacity': alpha_data.get('capacity', None),
'fitness': alpha_data.get('fitness', None),
'instrument_count': alpha_data.get('instrumentCount', None),
'start_date': alpha_data.get('startDate', None),
'end_date': alpha_data.get('endDate', None),
})
except Exception as e:
metrics['error'] = f"解析指标时出错: {str(e)}"
return metrics
def close(self):
"""关闭连接"""
@ -109,8 +186,8 @@ class AlphaSimulationManager:
self.credentials_file = credentials_file
self.results = []
"""将秒数格式化为 xx分xx秒 格式"""
def format_time(self, seconds):
"""将秒数格式化为 xx分xx秒 格式"""
if seconds < 60:
return f"{seconds:.2f}"
else:
@ -118,8 +195,8 @@ class AlphaSimulationManager:
remaining_seconds = seconds % 60
return f"{minutes}{remaining_seconds:.2f}"
"""模拟单个Alpha因子(线程安全)"""
def simulate_single_alpha(self, api, expression, settings=None):
"""模拟单个Alpha因子(线程安全)"""
alpha_start_time = time.time()
try:
@ -137,11 +214,49 @@ class AlphaSimulationManager:
"formatted_time": self.format_time(time_consuming),
"alpha_id": simulation_result["alpha_id"],
"status": "success",
"description": "/"
"description": "/",
"simulation_timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
# 性能指标
"performance_metrics": {
"sharpe_ratio": simulation_result["metrics"].get('sharpe_ratio'),
"annual_return": simulation_result["metrics"].get('annual_return'),
"annual_volatility": simulation_result["metrics"].get('annual_volatility'),
"max_drawdown": simulation_result["metrics"].get('max_drawdown'),
"information_ratio": simulation_result["metrics"].get('information_ratio'),
"total_return": simulation_result["metrics"].get('total_return'),
},
# 风险指标
"risk_metrics": {
"turnover": simulation_result["metrics"].get('turnover'),
"score": simulation_result["metrics"].get('score'),
"specific_return": simulation_result["metrics"].get('specific_return'),
"specific_risk": simulation_result["metrics"].get('specific_risk'),
"tail_ratio": simulation_result["metrics"].get('tail_ratio'),
"common_ratio": simulation_result["metrics"].get('common_ratio'),
},
# 分位数指标
"quantile_metrics": {
"top_minus_bottom": simulation_result["metrics"].get('top_minus_bottom'),
"top_decile_return": simulation_result["metrics"].get('top_decile_return'),
"bottom_decile_return": simulation_result["metrics"].get('bottom_decile_return'),
"ic": simulation_result["metrics"].get('ic'),
"ic_decay": simulation_result["metrics"].get('ic_decay'),
},
# 其他指标
"other_metrics": {
"capacity": simulation_result["metrics"].get('capacity'),
"fitness": simulation_result["metrics"].get('fitness'),
"instrument_count": simulation_result["metrics"].get('instrument_count'),
"start_date": simulation_result["metrics"].get('start_date'),
"end_date": simulation_result["metrics"].get('end_date'),
}
}
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 = {
@ -150,7 +265,12 @@ class AlphaSimulationManager:
"formatted_time": self.format_time(time_consuming),
"alpha_id": "/",
"status": "error",
"description": simulation_result["message"]
"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']}")
@ -166,15 +286,42 @@ class AlphaSimulationManager:
"formatted_time": self.format_time(time_consuming),
"alpha_id": "/",
"status": "failed",
"description": str(e)
"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
key_metrics = [
('夏普比率', 'sharpe_ratio'),
('年化收益', 'annual_return'),
('最大回撤', 'max_drawdown'),
('信息比率', 'information_ratio'),
('总分', 'score'),
]
print(" 关键指标:")
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}")
"""模拟一批Alpha因子(3个一组)"""
def simulate_alpha_batch(self, alpha_batch, batch_number):
"""模拟一批Alpha因子(3个一组)"""
print(f"\n{'=' * 60}")
print(f"开始第 {batch_number} 批因子模拟 (共 {len(alpha_batch)} 个因子)")
print(f"因子列表: {alpha_batch}")
@ -215,8 +362,8 @@ class AlphaSimulationManager:
return batch_results
"""运行批量模拟"""
def run_simulation(self, alpha_list, batch_size=3):
"""运行批量模拟"""
print("开始Alpha因子批量模拟...")
total_start_time = time.time()
@ -247,8 +394,8 @@ class AlphaSimulationManager:
return all_results
"""打印结果汇总"""
def print_summary(self, results, total_time):
"""打印结果汇总"""
print(f"\n{'=' * 60}")
print("模拟结果汇总")
print(f"{'=' * 60}")
@ -274,13 +421,21 @@ class AlphaSimulationManager:
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 文件夹中

Loading…
Cancel
Save