test001.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. """
  2. WQC Chapter2 速通脚本
  3. 生成20条Delay1-USA因子 -> 体检 -> 返回第一条五项全绿因子
  4. """
  5. import pandas as pd
  6. import numpy as np
  7. from wq_core import alpha, get_univ # 网页Notebook已内置
  8. # ---------- 参数 ----------
  9. REGION = 'USA'
  10. DELAY = 1
  11. UNIV = get_univ('TOP3000') # 教学关默认宇宙
  12. N_FACTOR = 20
  13. METRICS = ['fitness','sharpe','turnover','max_weight','sub_univ_ok']
  14. GREEN = {'fitness':1.0, 'sharpe':1.25, 'turnover':(1,70), 'max_weight':10, 'sub_univ_ok':True}
  15. # ---------- 1. 因子定义池 ----------
  16. raw_expr = {
  17. 'mom5' : 'rank(ts_return(close,5))',
  18. 'mom10' : 'rank(ts_return(close,10))',
  19. 'rev5' : 'rank(-ts_return(close,5))',
  20. 'rev10' : 'rank(-ts_return(close,10))',
  21. 'vol10' : 'rank(-ts_std(return,10))',
  22. 'vol20' : 'rank(-ts_std(return,20))',
  23. 'amt5' : 'rank(-ts_mean(amount,5))', # 短期缩量
  24. 'amt10' : 'rank(-ts_mean(amount,10))',
  25. 'illiq10': 'rank(ts_mean(abs(return)/amount,10))', # 非流动
  26. 'illiq20': 'rank(ts_mean(abs(return)/amount,20))',
  27. # 以下再加半衰变体
  28. 'mom5_d7': 'rank(ts_decay_linear(ts_return(close,5),7))',
  29. 'mom5_d10':'rank(ts_decay_linear(ts_return(close,5),10))',
  30. 'rev5_d7': 'rank(-ts_decay_linear(ts_return(close,5),7))',
  31. 'vol10_d7':'rank(-ts_decay_linear(ts_std(return,10),7))',
  32. 'amt5_d7': 'rank(-ts_decay_linear(ts_mean(amount,5),7))',
  33. 'illiq10_d7':'rank(ts_decay_linear(ts_mean(abs(return)/amount,10),7))',
  34. # 反转+波动组合
  35. 'rev_vol':'rank(-ts_return(close,5)*ts_std(return,10))',
  36. 'mom_vol':'rank(ts_return(close,5)/ts_std(return,10))',
  37. 'amt_rev':'rank(-ts_mean(amount,5)*ts_return(close,5))',
  38. }
  39. # ---------- 2. 批量生成+体检 ----------
  40. result = []
  41. for name, expr in raw_expr.items():
  42. fac = alpha(expr, UNIV, delay=DELAY)
  43. rpt = fac.test(region=REGION, delay=DELAY) # 返回dict
  44. rpt['name'] = name
  45. rpt['expr'] = expr
  46. result.append(rpt)
  47. df = pd.DataFrame(result)
  48. # ---------- 3. 过滤全绿 ----------
  49. def is_green(row):
  50. ok = (row.fitness >= GREEN['fitness'] and
  51. row.sharpe >= GREEN['sharpe'] and
  52. GREEN['turnover'][0] <= row.turnover <= GREEN['turnover'][1] and
  53. row.max_weight <= GREEN['max_weight'] and
  54. row.sub_univ_ok == GREEN['sub_univ_ok'])
  55. return ok
  56. greens = df[df.apply(is_green, axis=1)].reset_index(drop=True)
  57. # ---------- 4. 输出 ----------
  58. if greens.empty:
  59. print('>>> 暂无全绿因子,尝试调半衰期或再中性化 <<<')
  60. else:
  61. pick = greens.iloc[0] # 首条即可提交
  62. print('>>> 发现全绿因子!直接复制下方代码去提交页 <<<')
  63. print(f'# 因子名: {pick.name}')
  64. print(f'expression = "{pick.expr}"')
  65. print(f'# Fitness={pick.fitness:.2f} Sharpe={pick.sharpe:.2f} '
  66. f'Turnover={pick.turnover:.1f}% MaxWeight={pick.max_weight:.1f}%')