update
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
+171
-16
@@ -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 文件夹中
|
||||
|
||||
Reference in New Issue
Block a user