You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
alpha_tools/hide_low_sharpe_alpha/hide_low_sharpe_alpha.py

239 lines
7.0 KiB

# -*- coding: utf-8 -*-
"""
批量隐藏低质量Alpha
目标URL: https://api.worldquantbrain.com/users/self/alphas?limit=22&offset=0&status=UNSUBMITTED%1FIS_FAIL&is.sharpe%3C0.7&is.sharpe%3E-0.8&is.turnover%3C0.2&order=-is.sharpe&hidden=false
隐藏接口: PATCH https://api.worldquantbrain.com/alphas/{alpha_id}
Payload: {"hidden":true}
"""
import random
import time
import httpx
from httpx import BasicAuth
# 全局配置
TIMEOUT = 10.0 # 请求超时时间(秒)
MAX_RETRIES = 3 # 最大重试次数
RETRY_DELAY_MIN = 3 # 重试最小等待时间(秒)
RETRY_DELAY_MAX = 5 # 重试最大等待时间(秒)
MAX_LIMIT = 100 # 每页最大数量
MAX_PAGE = 5 # 最大页数
def login():
"""登录WorldQuant Brain API"""
# 从nacos获取账号密码
nacos_resp = httpx.get('http://192.168.31.41:30848/nacos/v1/cs/configs?dataId=wq_account&group=quantify')
if nacos_resp.status_code != 200:
print('获取账号密码失败')
return False
config = nacos_resp.json()
username = config['user_name']
password = config['password']
print(f"正在登录账户: {username}")
# 创建客户端并认证,设置超时
client = httpx.Client(auth=BasicAuth(username, password), timeout=TIMEOUT)
# 发送登录请求
response = client.post('https://api.worldquantbrain.com/authentication')
print(f"登录状态: {response.status_code}")
if response.status_code == 201:
print("登录成功!")
print(response.json())
return client
else:
print(f"登录失败: {response.json()}")
client.close()
return None
def request_with_retry(client, method, url, **kwargs):
"""
带重试机制的请求函数
默认重试3次,每次等待3-5秒
"""
for attempt in range(1, MAX_RETRIES + 1):
try:
print(f" 请求尝试 {attempt}/{MAX_RETRIES}: {method.upper()} {url}")
response = client.request(method, url, **kwargs)
return response
except Exception as e:
print(f" 请求异常: {str(e)}")
if attempt < MAX_RETRIES:
sleep_time = random.uniform(RETRY_DELAY_MIN, RETRY_DELAY_MAX)
print(f" 等待 {sleep_time:.2f} 秒后重试...")
time.sleep(sleep_time)
else:
print(f" 已达到最大重试次数 {MAX_RETRIES},放弃请求")
raise
return None
def fetch_all_alphas(client, base_url):
"""
分页获取所有符合条件的alpha
返回alpha信息列表(包含id和is数据)
使用for循环,步进MAX_LIMIT,最多获取MAX_PAGE页
"""
alphas = []
for page in range(MAX_PAGE):
# 计算当前页的offset
offset = page * MAX_LIMIT
# 构建当前页的URL
url = f"{base_url}&offset={offset}"
print(f"\n正在获取第 {page + 1}/{MAX_PAGE} 页,offset={offset} 的数据...")
try:
response = request_with_retry(client, 'get', url)
except Exception as e:
print(f"获取数据失败: {str(e)}")
break
if response.status_code != 200:
print(f"获取数据失败: {response.status_code}")
print(f"响应: {response.text}")
break
data = response.json()
results = data.get('results', [])
# 如果没有结果,说明已经获取完毕
if not results:
print("\n没有更多数据,获取完成")
break
# 提取当前页的alpha信息
for alpha in results:
alpha_info = {
'id': alpha.get('id'),
'is': alpha.get('is', {})
}
if alpha_info['id']:
alphas.append(alpha_info)
print(f" 发现Alpha: {alpha_info['id']}")
print(f"本页获取完成,共 {len(results)} 个Alpha")
sleep_time = random.uniform(3, 5)
print(f"等待 {sleep_time:.2f} 秒后继续获取下一页数据...")
time.sleep(sleep_time)
return alphas
def hide_alpha(client, alpha_info):
"""
隐藏单个Alpha
PATCH https://api.worldquantbrain.com/alphas/{alpha_id}
Payload: {"hidden":true}
隐藏后输出is数据
"""
alpha_id = alpha_info['id']
is_data = alpha_info.get('is', {})
url = f"https://api.worldquantbrain.com/alphas/{alpha_id}"
payload = {"hidden": True}
try:
response = request_with_retry(client, 'patch', url, json=payload)
if response.status_code in [200, 204]:
# 输出is数据
sharpe = is_data.get('sharpe', 'N/A')
fitness = is_data.get('fitness', 'N/A')
margin = is_data.get('margin', 'N/A')
drawdown = is_data.get('drawdown', 'N/A')
returns = is_data.get('returns', 'N/A')
print(f" ✓ Alpha {alpha_id} 隐藏成功")
print(f" sharpe={sharpe}, fitness={fitness}, margin={margin}, drawdown={drawdown}, returns={returns}")
return True
else:
print(f" ✗ Alpha {alpha_id} 隐藏失败: {response.status_code}")
print(f" 响应: {response.text}")
return False
except Exception as e:
print(f" ✗ Alpha {alpha_id} 隐藏异常: {str(e)}")
return False
def batch_hide_alphas(client, alphas):
"""
批量隐藏Alpha
"""
total = len(alphas)
success_count = 0
fail_count = 0
print(f"\n开始批量隐藏 {total} 个Alpha...")
print("=" * 50)
for index, alpha_info in enumerate(alphas, 1):
alpha_id = alpha_info['id']
print(f"[{index}/{total}] 正在隐藏 Alpha: {alpha_id}")
if hide_alpha(client, alpha_info):
success_count += 1
else:
fail_count += 1
time.sleep(0.5)
print("=" * 50)
print(f"批量隐藏完成!")
print(f"成功: {success_count}")
print(f"失败: {fail_count}")
return success_count, fail_count
def run(client):
# 目标URL(获取未隐藏的、低sharpe的alpha)
TARGET_URL = "https://api.worldquantbrain.com/users/self/alphas?limit=100&offset=0&status=UNSUBMITTED%1FIS_FAIL&is.sharpe%3C0.65&is.sharpe%3E-0.8&is.turnover%3C0.2&order=-is.sharpe&hidden=false"
if client:
try:
print("\n" + "=" * 50)
print("获取所有符合条件的Alpha")
print("=" * 50)
alphas = fetch_all_alphas(client, TARGET_URL)
if not alphas:
print("没有找到需要隐藏的Alpha")
exit(1)
else:
print(f"\n总共找到 {len(alphas)} 个需要隐藏的Alpha")
print("\n" + "=" * 50)
print("批量隐藏Alpha")
print("=" * 50)
success, fail = batch_hide_alphas(client, alphas)
except Exception as e:
print(str(e))
else:
print("登录失败,程序退出")
def main():
# 登录
client = login()
while True:
run(client)
time.sleep(60)
if __name__ == '__main__':
main()