commit ee0dd954c880e4562fb1734233af3d40ef83a4f9 Author: jack Date: Thu Nov 13 10:32:55 2025 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4383d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,233 @@ +# ========================= +# 操作系统文件 +# ========================= + +# macOS +.DS_Store +.AppleDouble +.LSOverride +Icon? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Windows +Desktop.ini +$RECYCLE.BIN/ +*.lnk + +# Linux +*~ + +# ========================= +# PyCharm 文件 +# ========================= + +# PyCharm 项目文件 +.idea/ +*.iws +*.iml +*.ipr + +# PyCharm 缓存目录 +out/ + +# 插件 +/.idea/modules.xml +/.idea/workspace.xml + +# 数据库工具相关 +*.db + +# ========================= +# VSCode 文件 +# ========================= + +.vscode/ +*.code-workspace + +# VSCode 本地历史文件 +.history/ + +# ========================= +# Python 文件 +# ========================= + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# ========================= +# 其他开发工具 +# ========================= + +# Sublime Text +*.sublime-* + +# Vim +*.swp +*.swo +*~ + +# IntelliJ +*.class + +# Eclipse +.project +.classpath +.settings/ + +# NetBeans +nbproject/ + +# ========================= +# 日志文件 +# ========================= + +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# ========================= +# 临时文件 +# ========================= + +# 临时文件 +*.tmp +*.temp +*.bak +*.backup + +# 系统临时文件 +*.~lock.* \ No newline at end of file diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..e69de29 diff --git a/demo_generating_factor/test001.py b/demo_generating_factor/test001.py new file mode 100644 index 0000000..901cbdf --- /dev/null +++ b/demo_generating_factor/test001.py @@ -0,0 +1,73 @@ +""" +WQC Chapter2 速通脚本 +生成20条Delay1-USA因子 -> 体检 -> 返回第一条五项全绿因子 +""" +import pandas as pd +import numpy as np +from wq_core import alpha, get_univ # 网页Notebook已内置 + +# ---------- 参数 ---------- +REGION = 'USA' +DELAY = 1 +UNIV = get_univ('TOP3000') # 教学关默认宇宙 +N_FACTOR = 20 +METRICS = ['fitness','sharpe','turnover','max_weight','sub_univ_ok'] +GREEN = {'fitness':1.0, 'sharpe':1.25, 'turnover':(1,70), 'max_weight':10, 'sub_univ_ok':True} + +# ---------- 1. 因子定义池 ---------- +raw_expr = { + 'mom5' : 'rank(ts_return(close,5))', + 'mom10' : 'rank(ts_return(close,10))', + 'rev5' : 'rank(-ts_return(close,5))', + 'rev10' : 'rank(-ts_return(close,10))', + 'vol10' : 'rank(-ts_std(return,10))', + 'vol20' : 'rank(-ts_std(return,20))', + 'amt5' : 'rank(-ts_mean(amount,5))', # 短期缩量 + 'amt10' : 'rank(-ts_mean(amount,10))', + 'illiq10': 'rank(ts_mean(abs(return)/amount,10))', # 非流动 + 'illiq20': 'rank(ts_mean(abs(return)/amount,20))', + # 以下再加半衰变体 + 'mom5_d7': 'rank(ts_decay_linear(ts_return(close,5),7))', + 'mom5_d10':'rank(ts_decay_linear(ts_return(close,5),10))', + 'rev5_d7': 'rank(-ts_decay_linear(ts_return(close,5),7))', + 'vol10_d7':'rank(-ts_decay_linear(ts_std(return,10),7))', + 'amt5_d7': 'rank(-ts_decay_linear(ts_mean(amount,5),7))', + 'illiq10_d7':'rank(ts_decay_linear(ts_mean(abs(return)/amount,10),7))', + # 反转+波动组合 + 'rev_vol':'rank(-ts_return(close,5)*ts_std(return,10))', + 'mom_vol':'rank(ts_return(close,5)/ts_std(return,10))', + 'amt_rev':'rank(-ts_mean(amount,5)*ts_return(close,5))', +} + +# ---------- 2. 批量生成+体检 ---------- +result = [] +for name, expr in raw_expr.items(): + fac = alpha(expr, UNIV, delay=DELAY) + rpt = fac.test(region=REGION, delay=DELAY) # 返回dict + rpt['name'] = name + rpt['expr'] = expr + result.append(rpt) + +df = pd.DataFrame(result) + +# ---------- 3. 过滤全绿 ---------- +def is_green(row): + ok = (row.fitness >= GREEN['fitness'] and + row.sharpe >= GREEN['sharpe'] and + GREEN['turnover'][0] <= row.turnover <= GREEN['turnover'][1] and + row.max_weight <= GREEN['max_weight'] and + row.sub_univ_ok == GREEN['sub_univ_ok']) + return ok + +greens = df[df.apply(is_green, axis=1)].reset_index(drop=True) + +# ---------- 4. 输出 ---------- +if greens.empty: + print('>>> 暂无全绿因子,尝试调半衰期或再中性化 <<<') +else: + pick = greens.iloc[0] # 首条即可提交 + print('>>> 发现全绿因子!直接复制下方代码去提交页 <<<') + print(f'# 因子名: {pick.name}') + print(f'expression = "{pick.expr}"') + print(f'# Fitness={pick.fitness:.2f} Sharpe={pick.sharpe:.2f} ' + f'Turnover={pick.turnover:.1f}% MaxWeight={pick.max_weight:.1f}%') \ No newline at end of file diff --git a/demo_yfinance/demo.py b/demo_yfinance/demo.py new file mode 100644 index 0000000..585f7bb --- /dev/null +++ b/demo_yfinance/demo.py @@ -0,0 +1,35 @@ +import os +os.environ["http_proxy"] = "http://127.0.0.1:7890" +os.environ["https_proxy"] = "http://127.0.0.1:7890" + +# pip install yfinance +import yfinance as yf +from datetime import datetime + +def crypto_last(ticker: str) -> float: + """ + 返回某个币对 USD 的最新收盘价(1m 线最近一次) + ticker 示例: "BTC-USD", "ETH-USD", "SOL-USD" + """ + data = yf.download( + tickers=ticker, + period="1d", + interval="1m", + auto_adjust=True, + progress=False, + threads=False + ) + if data.empty: + raise RuntimeError("yfinance 返回为空,可能 ticker 写错或网络问题") + # 关键修正:把 Series 转成标量 + last_close = data["Close"].iloc[-1].item() + return last_close + +if __name__ == "__main__": + pairs = ["BTC-USD", "ETH-USD", "SOL-USD", "SUI-USD"] + for p in pairs: + try: + price = crypto_last(p) + except Exception as e: + print(e) + print(f"{datetime.now():%Y-%m-%d %H:%M:%S} {p}: {price}") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..943271e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,32 @@ +# 核心数据分析 +pandas>=2.0.0 +numpy>=1.24.0 + +# 可视化 +matplotlib>=3.7.0 +seaborn>=0.12.0 + +# 量化交易 +backtrader>=1.9.78 +yfinance>=0.2.18 +## brew install ta-lib +ta-lib>=0.4.25 + +# 机器学习 +scikit-learn>=1.3.0 +xgboost>=1.7.0 + +# 工具库 +httpx>=0.28.1 +tqdm>=4.65.0 + +# PyTorch 生态系统 +torch>=2.0.0 +torchvision>=0.15.0 +torchaudio>=2.0.0 +pytorch-lightning>=2.0.0 +torchinfo>=1.7.0 + +# 时间序列深度学习 +pytorch-forecasting>=1.0.0 +pytorch-tabular>=1.0.0 diff --git a/wq101alphas/alpha101_code/01-alpha因子编写 b/wq101alphas/alpha101_code/01-alpha因子编写 new file mode 100644 index 0000000..6421845 --- /dev/null +++ b/wq101alphas/alpha101_code/01-alpha因子编写 @@ -0,0 +1,619 @@ +from scipy.stats import rankdata +from dateutil import parser +import numpy as np +import numpy.linalg as la +import pandas as pd +from datetime import datetime +import scipy.stats as stats +import matplotlib.pyplot as plt +from WindPy import * # 万矿数据接口 +w.start() + +## 内置函数 +# 行业中性化 +def neutral(data,ind): + stocks = list(data.index) + data_ = pd.DataFrame(ind.Data,index=['INDUSTRY'],columns=ind.Codes).T + data_med = pd.get_dummies(data_,columns=['INDUSTRY']) + X= np.array(data_med) + y = data.values + beta_ols = la.inv(X.T.dot(X)).dot(X.T).dot(y) + residual = y - X.dot(beta_ols) + return residual +def IndNeutralize(vwap,ind): + vwap_ = vwap.fillna(value = 0) + ind = w.wss(stocks, "industry_citic","unit=1;tradeDate="+ind.Times[0].strftime("%Y%m%d")+";industryType=1") + for i in range(len(vwap_)): + vwap_.iloc[i] = neutral(vwap_.iloc[i],ind) + return vwap_ +# 移动求和 +def ts_sum(df, window): + return df.rolling(window).sum() +# 移动平均 +def sma(df, window): + return df.rolling(window).mean() +# 移动标准差 +def stddev(df, window): + return df.rolling(window).std() +# 移动相关系数 +def correlation(x, y, window): + return x.rolling(window).corr(y) +# 移动协方差 +def covariance(x, y, window): + return x.rolling(window).cov(y) +# 在过去d天的时序排名 +def rolling_rank(na): + return rankdata(na)[-1] +def ts_rank(df,window): + return df.rolling(window).apply(rolling_rank) +# 过去d天的时序乘积 +def rolling_prod(na): + return np.prod(na) +def product(df, window): + return df.rolling(window).apply(rolling_prod) +# 过去d天最小值 +def ts_min(df, window): + return df.rolling(window).min() +# 过去d天最大值 +def ts_max(df, window): + return df.rolling(window).max() +# 当天取值减去d天前的值 +def delta(df, period): + return df.diff(period) +# d天前的值,滞后值 +def delay(df, period): + return df.shift(period) +# 截面数据排序,输出boolean值 +def rank(df): + return df.rank(pct=True,axis=1) +# 缩放时间序列,使其和为1 +def scale(df, k=1): + return df.mul(k).div(np.abs(df).sum()) +# 过去d天最大值的位置 +def ts_argmax(df, window): + return df.rolling(window).apply(np.argmax) + 1 +# 过去d天最小值的位置 +def ts_argmin(df, window): + return df.rolling(window).apply(np.argmin) + 1 +# 线性衰减的移动平均加权 +def decay_linear(df, period): + if df.isnull().values.any(): + df.fillna(method='ffill', inplace=True) + df.fillna(method='bfill', inplace=True) + df.fillna(value=0, inplace=True) + na_lwma = np.zeros_like(df) # 生成与df大小相同的零数组 + na_lwma[:period, :] = df.iloc[:period, :] # 赋前period项的值 + na_series = df.as_matrix() + # 计算加权系数 + divisor = period * (period + 1) / 2 + y = (np.arange(period) + 1) * 1.0 / divisor + # 从第period项开始计算数值 + for row in range(period - 1, df.shape[0]): + x = na_series[row - period + 1: row + 1, :] + na_lwma[row, :] = (np.dot(x.T, y)) + return pd.DataFrame(na_lwma,index = df.index,columns = df.columns) + +## 因子函数 +def alpha1(close,returns): + x = close + x[returns < 0] = stddev(returns,20) + alpha = rank(ts_argmax(x ** 2, 5))-0.5 + return alpha.fillna(value = 0) +def alpha2(Open,close,volume): + r1 = rank(delta(np.log(volume), 2)) + r2 = rank((close - Open) / Open) + alpha = -1 * correlation(r1,r2,6) + return alpha.fillna(value = 0) +def alpha3(Open,volume): + r1 = rank(Open) + r2 = rank(volume) + alpha = -1 * correlation(r1,r2,10) + return alpha.replace([-np.inf, np.inf], 0).fillna(value = 0) +def alpha4(low): + r = rank(low) + alpha = -1 * ts_rank(r,9) + return alpha.fillna(value = 0) +def alpha5(Open,vwap,close): + alpha = (rank((Open - (ts_sum(vwap, 10) / 10))) * (-1 * abs(rank((close - vwap))))) + return alpha.fillna(value = 0) +def alpha6(Open, volume): + alpha = -1 * correlation(Open, volume, 10) + return alpha.replace([-np.inf, np.inf], 0).fillna(value = 0) +def alpha7(volume,close): + adv20 = sma(volume, 20) + alpha = -1 * ts_rank(abs(delta(close, 7)), 60) * np.sign(delta(close, 7)) + alpha[adv20 >= volume] = -1 + return alpha.fillna(value = 0) +def alpha8(Open,returns): + x1 = (ts_sum(Open, 5) * ts_sum(returns, 5)) + x2 = delay((ts_sum(Open, 5) * ts_sum(returns, 5)), 10) + alpha = -1 * rank(x1-x2) + return alpha.fillna(value = 0) +def alpha9(close): + delta_close = delta(close, 1) + x1 = ts_min(delta_close, 5) > 0 + x2 = ts_max(delta_close, 5) < 0 + alpha = -1 * delta_close + alpha[x1 | x2] = delta_close + return alpha.fillna(value = 0) +def alpha10(close): + delta_close = delta(close, 1) + x1 = ts_min(delta_close, 4) > 0 + x2 = ts_max(delta_close, 4) < 0 + x = -1 * delta_close + x[x1 | x2] = delta_close + alpha = rank(x) + return alpha.fillna(value = 0) +def alpha11(vwap,close,volume): + x1 = rank(ts_max((vwap - close), 3)) + x2 = rank(ts_min((vwap - close), 3)) + x3 = rank(delta(volume, 3)) + alpha = (x1 + x2) * x3 + return alpha.fillna(value = 0) +def alpha12(volume,close): + alpha = np.sign(delta(volume, 1)) * (-1 * delta(close, 1)) + return alpha.fillna(value = 0) +def alpha13(volume,close): + alpha = -1 * rank(covariance(rank(close), rank(volume), 5)) + return alpha.fillna(value = 0) +def alpha14(Open,volume,returns): + x1 = correlation(Open, volume, 10).replace([-np.inf, np.inf], 0).fillna(value=0) + x2 = -1 * rank(delta(returns, 3)) + alpha = x1 * x2 + return alpha.fillna(value = 0) +def alpha15(high,volume): + x1 = correlation(rank(high), rank(volume), 3).replace([-np.inf, np.inf], 0).fillna(value=0) + alpha = -1 * ts_sum(rank(x1), 3) + return alpha.fillna(value = 0) +def alpha16(high,volume): + alpha = -1 * rank(covariance(rank(high), rank(volume), 5)) + return alpha.fillna(value = 0) +def alpha17(volume,close): + adv20 = sma(volume, 20) + x1 = rank(ts_rank(close, 10)) + x2 = rank(delta(delta(close, 1), 1)) + x3 = rank(ts_rank((volume / adv20), 5)) + alpha = -1 * (x1 * x2 * x3) + return alpha.fillna(value = 0) +def alpha18(close,Open): + x = correlation(close, Open, 10).replace([-np.inf, np.inf], 0).fillna(value=0) + alpha = -1 * (rank((stddev(abs((close - Open)), 5) + (close - Open)) + x)) + return alpha.fillna(value = 0) +def alpha19(close,returns): + x1 = (-1 * np.sign((close - delay(close, 7)) + delta(close, 7))) + x2 = (1 + rank(1 + ts_sum(returns, 250))) + alpha = x1 * x2 + return alpha.fillna(value = 0) +def alpha20(Open,high,close,low): + alpha = -1 * (rank(Open - delay(high, 1)) * rank(Open - delay(close, 1)) * rank(Open - delay(low, 1))) + return alpha.fillna(value = 0) +def alpha21(volume,close): + x1 = sma(close, 8) + stddev(close, 8) < sma(close, 2) + x2 = sma(close, 8) - stddev(close, 8) > sma(close, 2) + x3 = sma(volume, 20) / volume < 1 + alpha = pd.DataFrame(np.ones_like(close), index = close.index,columns = close.columns) + alpha[x1 | x3] = -1 * alpha + return alpha +def alpha22(high,volume,close): + x = correlation(high, volume, 5).replace([-np.inf, np.inf], 0).fillna(value=0) + alpha = -1 * delta(x, 5) * rank(stddev(close, 20)) + return alpha.fillna(value = 0) +def alpha23(high,close): + x = sma(high, 20) < high + alpha = pd.DataFrame(np.zeros_like(close),index = close.index,columns = close.columns) + alpha[x] = -1 * delta(high, 2).fillna(value = 0) + return alpha +def alpha24(close): + x = delta(sma(close, 100), 100) / delay(close, 100) <= 0.05 + alpha = -1 * delta(close, 3) + alpha[x] = -1 * (close - ts_min(close, 100)) + return alpha.fillna(value = 0) +def alpha25(volume,returns,vwap,high,close): + adv20 = sma(volume, 20) + alpha = rank((((-1 * returns) * adv20) * vwap) * (high - close)) + return alpha.fillna(value = 0) +def alpha26(volume,high): + x = correlation(ts_rank(volume, 5), ts_rank(high, 5), 5).replace([-np.inf, np.inf], 0).fillna(value=0) + alpha = -1 * ts_max(x, 3) + return alpha.fillna(value = 0) +def alpha27(volume,vwap): + alpha = rank((sma(correlation(rank(volume), rank(vwap), 6), 2) / 2.0)) + alpha[alpha > 0.5] = -1 + alpha[alpha <= 0.5] = 1 + return alpha.fillna(value = 0) +def alpha28(volume,high,low,close): + adv20 = sma(volume, 20) + x = correlation(adv20, low, 5).replace([-np.inf, np.inf], 0).fillna(value=0) + alpha = scale(((x + ((high + low) / 2)) - close)) + return alpha.fillna(value = 0) +def alpha29(close,returns): + x1 = ts_min(rank(rank(scale(np.log(ts_sum(rank(rank(-1 * rank(delta((close - 1), 5)))), 2))))), 5) + x2 = ts_rank(delay((-1 * returns), 6), 5) + alpha = x1 + x2 + return alpha.fillna(value = 0) +def alpha30(close,volume): + delta_close = delta(close, 1) + x = np.sign(delta_close) + np.sign(delay(delta_close, 1)) + np.sign(delay(delta_close, 2)) + alpha = ((1.0 - rank(x)) * ts_sum(volume, 5)) / ts_sum(volume, 20) + return alpha.fillna(value = 0) +def alpha31(close,low,volume): + adv20 = sma(volume,20) + x1 = rank(rank(rank(decay_linear((-1 * rank(rank(delta(close, 10)))), 10)))) + x2 = rank((-1 * delta(close, 3))) + x3 = np.sign(scale(correlation(adv20, low, 12).replace([-np.inf, np.inf], 0).fillna(value=0))) + alpha = x1 + x2 + x3 + return alpha.fillna(value = 0) +def alpha32(close,vwap): + x = correlation(vwap, delay(close, 5),230).replace([-np.inf, np.inf], 0).fillna(value=0) + alpha = scale(((sma(close, 7)) - close)) + 20 * scale(x) + return alpha.fillna(value = 0) +def alpha33(Open,close): + alpha = rank(-1 + (Open / close)) + return alpha +def alpha34(close,returns): + x = (stddev(returns, 2) / stddev(returns, 5)).fillna(value = 0) + alpha = rank(2 - rank(x) - rank(delta(close, 1))) + return alpha.fillna(value = 0) +def alpha35(volume,close,high,low,returns): + x1 = ts_rank(volume, 32) + x2 = 1 - ts_rank(close + high - low, 16) + x3 = 1 - ts_rank(returns, 32) + alpha = (x1 * x2 * x3).fillna(value = 0) + return alpha +def alpha36(Open,close,volume,returns,vwap): + adv20 = sma(volume, 20) + x1 = 2.21 * rank(correlation((close - Open), delay(volume, 1), 15)) + x2 = 0.7 * rank((Open- close)) + x3 = 0.73 * rank(ts_rank(delay((-1 * returns), 6), 5)) + x4 = rank(abs(correlation(vwap,adv20, 6))) + x5 = 0.6 * rank((sma(close, 200) - Open) * (close - Open)) + alpha = x1 + x2 + x3 + x4 + x5 + return alpha.fillna(value = 0) +def alpha37(Open,close): + alpha = rank(correlation(delay(Open - close, 1), close, 200)) + rank(Open - close) + return alpha.fillna(value = 0) +def alpha38(close,Open): + x = (close / Open).replace([-np.inf, np.inf], 0).fillna(value=0) + alpha = -1 * rank(ts_rank(Open, 10)) * rank(x) + return alpha.fillna(value = 0) +def alpha39(volume,close,returns): + adv20 = sma(volume, 20) + x = -1 * rank(delta(close, 7)) * (1 - rank(decay_linear((volume / adv20), 9))) + alpha = x *(1 + rank(ts_sum(returns, 250))) + return alpha.fillna(value = 0) +def alpha40(high,volume): + alpha = -1 * rank(stddev(high, 10)) * correlation(high, volume, 10) + return alpha.fillna(value = 0) +def alpha41(high,low,vwap): + alpha = pow((high * low),0.5) - vwap + return alpha +def alpha42(vwap,close): + alpha = rank((vwap - close)) / rank((vwap + close)) + return alpha +def alpha43(volume,close): + adv20 = sma(volume, 20) + alpha = ts_rank(volume / adv20, 20) * ts_rank((-1 * delta(close, 7)), 8) + return alpha.fillna(value = 0) +def alpha44(high,volume): + alpha = -1 *correlation(high, rank(volume), 5).replace([-np.inf, np.inf], 0).fillna(value=0) + return alpha +def alpha45(close,volume): + x = correlation(close, volume, 2).replace([-np.inf, np.inf], 0).fillna(value=0) + alpha = -1 * (rank(sma(delay(close, 5), 20)) * x * rank(correlation(ts_sum(close, 5), ts_sum(close, 20), 2))) + return alpha.fillna(value = 0) +def alpha46(close): + x = ((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10) + alpha = (-1 * (close - delay(close, 1))) + alpha[x < 0] = 1 + alpha[x > 0.25] = -1 + return alpha.fillna(value = 0) +def alpha47(volume,close,high,vwap): + adv20 = sma(volume, 20) + alpha = ((rank((1 / close)) * volume) / adv20) * ((high * rank((high - close))) / sma(high, 5)) - rank((vwap - delay(vwap, 5))) + return alpha.fillna(value = 0) +def alpha49(close): + x = (((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10)) + alpha = (-1 * delta(close,1)) + alpha[x < -0.1] = 1 + return alpha.fillna(value = 0) +def alpha50(volume,vwap): + alpha = -1 * ts_max(rank(correlation(rank(volume), rank(vwap), 5)), 5) + return alpha.fillna(value = 0) +def alpha51(close): + inner = (((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10)) + alpha = (-1 * delta(close,1)) + alpha[inner < -0.05] = 1 + return alpha.fillna(value = 0) +def alpha52(returns,volume,low): + x = rank(((ts_sum(returns, 240) - ts_sum(returns, 20)) / 220)) + alpha = -1 * delta(ts_min(low, 5), 5) * x * ts_rank(volume, 5) + return alpha.fillna(value = 0) +def alpha53(close,high,low): + alpha = -1 * delta((((close - low) - (high - close)) / (close - low).replace(0, 0.0001)), 9) + return alpha.fillna(value = 0) +def alpha54(Open,close,high,low): + x = (low - high).replace(0, -0.0001) + alpha = -1 * (low - close) * (Open ** 5) / (x * (close ** 5)) + return alpha +def alpha55(high,low,close,volume): + x = (close - ts_min(low, 12)) / (ts_max(high, 12) - ts_min(low, 12)).replace(0, 0.0001) + alpha = -1 * correlation(rank(x), rank(volume), 6).replace([-np.inf, np.inf], 0).fillna(value=0) + return alpha +def alpha56(returns,cap): + alpha = 0 - (1 * (rank((sma(returns, 10) / sma(sma(returns, 2), 3))) * rank((returns * cap)))) + return alpha.fillna(value = 0) +def alpha57(close,vwap): + alpha = 0 - 1 * ((close - vwap) / decay_linear(rank(ts_argmax(close, 30)), 2)) + return alpha.fillna(value = 0) +def alpha60(close,high,low,volume): + x = ((close - low) - (high - close)) * volume / (high - low).replace(0, 0.0001) + alpha = - ((2 * scale(rank(x))) - scale(rank(ts_argmax(close, 10)))) + return alpha.fillna(value = 0) +def alpha61(volume,vwap): + adv180 = sma(volume, 180) + alpha = rank((vwap - ts_min(vwap, 16))) < rank(correlation(vwap, adv180, 18)) + return alpha +def alpha62(volume,high,low,Open,vwap): + adv20 = sma(volume, 20) + x1 = rank(correlation(vwap, ts_sum(adv20, 22), 10)) + x2 = rank(((rank(Open) + rank(Open)) < (rank(((high + low) / 2)) + rank(high)))) + alpha = x1 < x2 + return alpha*-1 +def alpha64(high,low,Open,volume,vwap): + adv120 = sma(volume, 120) + x1 = rank(correlation(ts_sum(((Open * 0.178404) + (low * (1 - 0.178404))), 13),ts_sum(adv120, 13), 17)) + x2 = rank(delta(((((high + low) / 2) * 0.178404) + (vwap * (1 -0.178404))), 3.69741)) + alpha = x1 < x2 + return alpha*-1 +def alpha65(volume,vwap,Open): + adv60 = sma(volume, 60) + x1 = rank(correlation(((Open * 0.00817205) + (vwap * (1 - 0.00817205))), ts_sum(adv60,9), 6)) + x2 = rank((Open - ts_min(Open, 14))) + alpha = x1 < x2 + return alpha*-1 +def alpha66(vwap,low,Open,high): + x1 = rank(decay_linear(delta(vwap, 4), 7)) + x2 = (((low* 0.96633) + (low * (1 - 0.96633))) - vwap) / (Open - ((high + low) / 2)) + alpha = (x1 + ts_rank(decay_linear(x2, 11), 7)) * -1 + return alpha.fillna(value = 0) +def alpha68(volume,high,close,low): + adv15 = sma(volume, 15) + x1 = ts_rank(correlation(rank(high), rank(adv15), 9), 14) + x2 = rank(delta(((close * 0.518371) + (low * (1 - 0.518371))), 1.06157)) + alpha = x1 < x2 + return alpha*-1 +def alpha71(volume,close,low,Open,vwap): + adv180 = sma(volume, 180) + x1 = ts_rank(decay_linear(correlation(ts_rank(close, 3), ts_rank(adv180,12), 18), 4), 16) + x2 = ts_rank(decay_linear((rank(((low + Open) - (vwap + vwap))).pow(2)), 16), 4) + alpha = x1 + alpha[x1 < x2] = x2 + return alpha.fillna(value = 0) +def alpha72(volume,high,low,vwap): + adv40 = sma(volume, 40) + x1 = rank(decay_linear(correlation(((high + low) / 2), adv40, 9), 10)) + x2 = rank(decay_linear(correlation(ts_rank(vwap, 4), ts_rank(volume, 19), 7), 3)) + alpha = (x1 / x2.replace(0, 0.0001)).fillna(value = 0) + return alpha +def alpha73(vwap,Open,low): + x1 = rank(decay_linear(delta(vwap, 5), 3)) + x2 = delta(((Open * 0.147155) + (low * (1 - 0.147155))), 2) / ((Open *0.147155) + (low * (1 - 0.147155))) + x3 = ts_rank(decay_linear((x2 * -1), 3), 17) + alpha = x1 + alpha[x1 < x3] = x3 + return -1 * alpha.fillna(value = 0) +def alpha74(volume,close,high,vwap): + adv30 = sma(volume, 30) + x1 = rank(correlation(close, ts_sum(adv30, 37), 15)) + x2 = rank(correlation(rank(((high * 0.0261661) + (vwap * (1 - 0.0261661)))), rank(volume), 11)) + alpha = x1 < x2 + return alpha*-1 +def alpha75(volume,vwap,low): + adv50 = sma(volume, 50) + alpha = rank(correlation(vwap, volume, 4)) < rank(correlation(rank(low), rank(adv50), 12)) + return alpha +def alpha77(volume,high,low,vwap): + adv40 = sma(volume, 40) + x1 = rank(decay_linear(((((high + low) / 2) + high) - (vwap + high)), 20)) + x2 = rank(decay_linear(correlation(((high + low) / 2), adv40, 3), 6)) + alpha = x1 + alpha[x1 > x2] = x2 + return alpha.fillna(value = 0) +def alpha78(volume,low,vwap): + adv40 = sma(volume, 40) + x1 = rank(correlation(ts_sum(((low * 0.352233) + (vwap * (1 - 0.352233))), 20), ts_sum(adv40, 20),7)) + x2 = rank(correlation(rank(vwap), rank(volume), 6)) + alpha = x1.pow(x2) + return alpha.fillna(value = 0) +def alpha81(volume,vwap): + adv10 = sma(volume, 10) + x1 = rank(np.log(product(rank((rank(correlation(vwap, ts_sum(adv10, 50), 8)).pow(4))), 15))) + x2 = rank(correlation(rank(vwap), rank(volume), 5)) + alpha = x1 < x2 + return alpha*-1 +def alpha83(high,low,close,volume): + x = rank(delay(((high - low) / (ts_sum(close, 5) / 5)), 2)) * rank(rank(volume)) + alpha = x / (((high - low) / (ts_sum(close, 5) / 5)) / (vwap - close)) + return alpha.fillna(value = 0) +def alpha84(vwap,close): + alpha = pow(ts_rank((vwap - ts_max(vwap, 15)), 21), delta(close,5)) + return alpha.fillna(value = 0) +def alpha85(volume,high,close,low): + adv30 = sma(volume, 30) + x1 = rank(correlation(((high * 0.876703) + (close * (1 - 0.876703))), adv30,10)) + alpha = x1.pow(rank(correlation(ts_rank(((high + low) / 2), 4), ts_rank(volume, 10), 7))) + return alpha.fillna(value = 0) +def alpha86(volume,close,Open,vwap): + adv20 = sma(volume, 20) + x1 = ts_rank(correlation(close, sma(adv20, 15), 6), 20) + x2 = rank(((Open+ close) - (vwap + Open))) + alpha = x1 < x2 + return alpha*-1 +def alpha88(volume,Open,low,high,close): + adv60 = sma(volume, 60) + x1 = rank(decay_linear(((rank(Open) + rank(low)) - (rank(high) + rank(close))),8)) + x2 = ts_rank(decay_linear(correlation(ts_rank(close, 8), ts_rank(adv60,21), 8), 7), 3) + alpha = x1 + alpha[x1 > x2] = x2 + return alpha.fillna(value = 0) +def alpha92(volume,high,low,close,Open): + adv30 = sma(volume, 30) + x1 = ts_rank(decay_linear(((((high + low) / 2) + close) < (low + Open)), 15), 19) + x2 = ts_rank(decay_linear(correlation(rank(low), rank(adv30), 8), 7),7) + alpha = x1 + alpha[x1 > x2] = x2 + return alpha.fillna(value = 0) +def alpha94(volume,vwap): + adv60 = sma(volume, 60) + x = rank((vwap - ts_min(vwap, 12))) + alpha = x.pow(ts_rank(correlation(ts_rank(vwap,20), ts_rank(adv60, 4), 18), 3))* -1 + return alpha.fillna(value = 0) +def alpha95(volume,high,low,Open): + adv40 = sma(volume, 40) + x = ts_rank((rank(correlation(sma(((high + low)/ 2), 19), sma(adv40, 19), 13)).pow(5)), 12) + alpha = rank((Open - ts_min(Open, 12))) < x + return alpha.fillna(value = 0) +def alpha96(volume,vwap,close): + adv60 = sma(volume, 60) + x1 = ts_rank(decay_linear(correlation(rank(vwap), rank(volume), 4),4), 8) + x2 = ts_rank(decay_linear(ts_argmax(correlation(ts_rank(close, 7),ts_rank(adv60, 4), 4), 13), 14), 13) + alpha = x1 + alpha[x1 < x2] = x2 + return alpha.fillna(value = 0) +def alpha98(volume,Open,vwap): + adv5 = sma(volume, 5) + adv15 = sma(volume, 15) + x1 = rank(decay_linear(correlation(vwap, sma(adv5, 26), 5), 7)) + alpha = x1 - rank(decay_linear(ts_rank(ts_argmin(correlation(rank(Open), rank(adv15), 21), 9),7), 8)) + return alpha.fillna(value = 0) +def alpha99(volume,high,low): + adv60 = sma(volume, 60) + x1 = rank(correlation(ts_sum(((high + low) / 2), 20), ts_sum(adv60,20), 9)) + x2 = rank(correlation(low, volume, 6)) + alpha = x1 < x2 + return alpha*-1 +def alpha101(close,Open,high,low): + alpha = (close - Open) / ((high - low) + 0.001) + return alpha + +def alpha48(close,ind): + r1 = (correlation(delta(close, 1), delta(delay(close, 1), 1), 250) * delta(close, 1)) / close + r2 = ts_sum((pow((delta(close, 1) / delay(close, 1)),2)), 250) + alpha = IndNeutralize(r1, ind) / r2 + return alpha.fillna(value = 0) + +def alpha58(vwap,volume,ind): + x = IndNeutralize(vwap, ind) + alpha = -1 * ts_rank(decay_linear(correlation(x, volume, 4), 8), 6) + return alpha.fillna(value = 0) + +def alpha59(vwap,volume,ind): + x = IndNeutralize(((vwap * 0.728317) + (vwap * (1 - 0.728317))), ind) + alpha = -1 * ts_rank(decay_linear(correlation(x, volume, 4), 16), 8) + return alpha.fillna(value = 0) + +def alpha63(volume,close,vwap,Open,ind): + adv180 = sma(volume, 180).fillna(value = 0) + r1 = rank(decay_linear(delta(IndNeutralize(close, ind), 2), 8)) + r2 = rank(decay_linear(correlation(((vwap * 0.318108) + (Open * (1 - 0.318108))), ts_sum(adv180, 37), 14), 12)) + alpha = -1 * (r1 - r2) + return alpha.fillna(value = 0) + +def alpha67(volume,vwap,high,ind): + adv20 = sma(volume, 20) + r = rank(correlation(IndNeutralize(vwap, ind), IndNeutralize(adv20, ind), 6)) + alpha = pow(rank(high - ts_min(high, 2)),r) * -1 + return alpha.fillna(value = 0) + +def alpha69(volume,vwap,ind,close): + adv20 = sma(volume, 20) + r1 = rank(ts_max(delta(IndNeutralize(vwap, ind), 3), 5)) + r2 = ts_rank(correlation(((close * 0.490655) + (vwap * (1 - 0.490655))), adv20, 5), 9) + alpha = pow(r1,r2) * -1 + return alpha.fillna(value = 0) + +def alpha70(close,ind,vwap): + adv50 = sma(volume, 50).fillna(value = 0) + r = ts_rank(correlation(IndNeutralize(close, ind), adv50, 18), 18) + alpha = pow(rank(delta(vwap, 1)),r) * -1 + return alpha.fillna(value = 0) + +def alpha76(volume,vwap,low,ind): + adv81 = sma(volume, 81).fillna(value = 0) + r1 = rank(decay_linear(delta(vwap, 1), 12)) + r2 = ts_rank(decay_linear(ts_rank(correlation(IndNeutralize(low, ind), adv81, 8), 20), 17), 19) + alpha = r1 + alpha[r1 < r2] = r2 + return alpha.fillna(value = 0) + +def alpha79(volume,close,Open,ind,vwap): + adv150 = sma(volume, 150).fillna(value = 0) + r1 = rank(delta(IndNeutralize(((close * 0.60733) + (Open * (1 - 0.60733))), ind), 1)) + r2 = rank(correlation(ts_rank(vwap, 4), ts_rank(adv150, 9), 15)) + alpha = (r1 < r2) * -1 + return alpha.fillna(value = 0) + +def alpha80(Open,high,ind): + adv10 = sma(volume, 10) + r1 = rank(np.sign(delta(IndNeutralize(((Open * 0.868128) + (high * (1 - 0.868128))), ind), 4))) + r2 = ts_rank(correlation(high, adv10, 5), 6) + alpha = pow(r1,r2) * -1 + return alpha.fillna(value = 0) + +def alpha82(Open,volume,ind): + r1 = rank(decay_linear(delta(Open, 1), 15)) + r2 = ts_rank(decay_linear(correlation(IndNeutralize(volume, ind), ((Open * 0.634196) + (Open * (1 - 0.634196))), 17), 7), 13) + alpha = r1 + alpha[r1 > r2] = r2 + return -1 * alpha.fillna(value = 0) + +def alpha87(volume,close,vwap): + adv81 = sma(volume, 81).fillna(value = 0) + r1 = rank(decay_linear(delta(((close * 0.369701) + (vwap * (1 - 0.369701))), 2), 3)) + r2 = ts_rank(decay_linear(abs(correlation(IndNeutralize(adv81, ind), close, 13)), 5), 14) + alpha = r1 + alpha[r1 < r2] = r2 + return -1 * alpha.fillna(value = 0) + +def alpha89(low,vwap,ind): + adv10 = sma(volume, 10) + r1 = ts_rank(decay_linear(correlation(((low * 0.967285) + (low * (1 - 0.967285))), adv10, 7), 6), 4) + r2 = ts_rank(decay_linear(delta(IndNeutralize(vwap, ind), 3), 10), 15) + alpha = r1 - r2 + return alpha.fillna(value = 0) + +def alpha90(volume,close,ind,low): + adv40 = sma(volume, 40).fillna(value = 0) + r1 = rank((close - ts_max(close, 5))) + r2 = ts_rank(correlation(IndNeutralize(adv40, ind), low, 5), 3) + alpha = pow(r1,r2) * -1 + return alpha.fillna(value = 0) + +def alpha91(close,ind,volume,vwap): + adv30 = sma(volume, 30) + r1 = ts_rank(decay_linear(decay_linear(correlation(IndNeutralize(close, ind), volume, 10), 16), 4), 5) + r2 = rank(decay_linear(correlation(vwap, adv30, 4), 3)) + alpha = (r1 - r2) * -1 + return alpha.fillna(value = 0) + +def alpha93(vwap,ind,volume,close): + adv81 = sma(volume, 81).fillna(value = 0) + r1 = ts_rank(decay_linear(correlation(IndNeutralize(vwap, ind), adv81, 17), 20), 8) + r2 = rank(decay_linear(delta(((close * 0.524434) + (vwap * (1 - 0.524434))), 3), 16)) + alpha = r1 / r2 + return alpha.fillna(value = 0) + +def alpha97(volume,low,vwap,ind): + adv60 = sma(volume, 60).fillna(value = 0) + r1 = rank(decay_linear(delta(IndNeutralize(((low * 0.721001) + (vwap * (1 - 0.721001))), ind), 3), 20)) + r2 = ts_rank(decay_linear(ts_rank(correlation(ts_rank(low, 8), ts_rank(adv60, 17), 5), 19), 16), 7) + alpha = (r1 - r2) * -1 + return alpha.fillna(value = 0) + +def alpha100(volume,close,low,high,ind): + adv20 = sma(volume, 20) + r1 = IndNeutralize(rank(((((close - low) - (high - close)) / (high - low)) * volume)), ind) + r2 = 1.5 * scale(IndNeutralize(r1, ind)) + r3 = scale(IndNeutralize((correlation(close, rank(adv20), 5) - rank(ts_argmin(close, 30))), ind)) + alpha = -1 * (r2 - r3) * (volume / adv20) + return alpha.fillna(value = 0) diff --git a/wq101alphas/alpha101_code/02-基于万矿计算因子数据 b/wq101alphas/alpha101_code/02-基于万矿计算因子数据 new file mode 100644 index 0000000..97dca8d --- /dev/null +++ b/wq101alphas/alpha101_code/02-基于万矿计算因子数据 @@ -0,0 +1,184 @@ +from WindPy import * +import numpy as np +import pandas as pd +from datetime import datetime +import matplotlib.pyplot as plt +w.start() + +## 获取股票池 +s_date = '2014-01-01' +e_date = '2016-01-01' +date = w.tdays(s_date, e_date, "preiod = D").Data[0] # 日期函数 +stocks = w.wset("sectorconstituent", "date="+e_date+";windcode=000906.SH").Data[1] # 中证800股票池 + +## 获取日频量价原始数据 +close = w.wsd(stocks,'close',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index']) +# 改日期索引为数字,考虑后文rolling函数应用的便捷性 +returns = w.wsd(stocks,'pct_chg',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index']) +Open = w.wsd(stocks,'open',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index']) +low = w.wsd(stocks,'low',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index']) +vwap = w.wsd(stocks,'vwap',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index']) +high = w.wsd(stocks,'high',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index']) +cap = w.wsd(stocks,'mkt_cap_ashare',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index']) +volume = w.wsd(stocks,'volume',s_date,e_date,usedf = True)[1].reset_index().drop(columns = ['index']) +ind = w.wss(stocks, "industry_citic","unit=1;tradeDate="+date[0].strftime("%Y%m%d")+";industryType=1") + +## 计算因子值 +start_1 = datetime.now() # 记录计算用时 + +alpha_1 = alpha1(close,returns) +alpha_2 = alpha2(Open,close,volume) +alpha_3 = alpha3(Open,volume) +alpha_4 = alpha4(low) +alpha_5 = alpha5(Open,vwap,close) +alpha_6 = alpha6(Open, volume) +alpha_7 = alpha7(volume,close) +alpha_8 = alpha8(Open,returns) +alpha_9 = alpha9(close) +alpha_10 = alpha10(close) +alpha_11 = alpha11(vwap,close,volume) +alpha_12 = alpha12(volume,close) +alpha_13 = alpha13(volume,close) +alpha_14 = alpha14(Open,volume,returns) +alpha_15 = alpha15(high,volume) +alpha_16 = alpha16(high,volume) +alpha_17 = alpha17(volume,close) +alpha_18 = alpha18(close,Open) +alpha_19 = alpha19(close,returns) +alpha_20 = alpha20(Open,high,close,low) +alpha_21 = alpha21(volume,close) +alpha_22 = alpha22(high,volume,close) +alpha_23 = alpha23(high,close) +alpha_24 = alpha24(close) +alpha_25 = alpha25(volume,returns,vwap,high,close) +alpha_26 = alpha26(volume,high) +alpha_27 = alpha27(volume,vwap) +alpha_28 = alpha28(volume,high,low,close) +alpha_29 = alpha29(close,returns) +alpha_30 = alpha30(close,volume) +alpha_31 = alpha31(close,low,volume) +alpha_32 = alpha32(close,vwap) +alpha_33 = alpha33(Open,close) +alpha_34 = alpha34(close,returns) +alpha_35 = alpha35(volume,close,high,low,returns) +alpha_36 = alpha36(Open,close,volume,returns,vwap) +alpha_37 = alpha37(Open,close) +alpha_38 = alpha38(close,Open) +alpha_39 = alpha39(volume,close,returns) +alpha_40 = alpha40(high,volume) +alpha_41 = alpha41(high,low,vwap) +alpha_42 = alpha42(vwap,close) +alpha_43 = alpha43(volume,close) +alpha_44 = alpha44(high,volume) +alpha_45 = alpha45(close,volume) +alpha_46 = alpha46(close) +alpha_47 = alpha47(volume,close,high,vwap) +alpha_49 = alpha49(close) +alpha_50 = alpha50(volume,vwap) +alpha_51 = alpha51(close) +alpha_52 = alpha52(returns,volume,low) +alpha_53 = alpha53(close,high,low) +alpha_54 = alpha54(Open,close,high,low) +alpha_55 = alpha55(high,low,close,volume) +alpha_56 = alpha56(returns,cap) +alpha_57 = alpha57(close,vwap) +alpha_60 = alpha60(close,high,low,volume) +alpha_61 = alpha61(volume,vwap) +alpha_62 = alpha62(volume,high,low,Open,vwap) +alpha_64 = alpha64(high,low,Open,volume,vwap) +alpha_65 = alpha65(volume,vwap,Open) +alpha_66 = alpha66(vwap,low,Open,high) +alpha_68 = alpha41(high,low,vwap) +alpha_71 = alpha71(volume,close,low,Open,vwap) +alpha_72 = alpha72(volume,high,low,vwap) +alpha_73 = alpha73(vwap,Open,low) +alpha_74 = alpha74(volume,close,high,vwap) +alpha_75 = alpha75(volume,vwap,low) +alpha_77 = alpha77(volume,high,low,vwap) +alpha_78 = alpha78(volume,low,vwap) +alpha_81 = alpha81(volume,vwap) +alpha_83 = alpha83(high,low,close,volume) +alpha_84 = alpha84(vwap,close) +alpha_85 = alpha85(volume,high,close,low) +alpha_86 = alpha41(high,low,vwap) +alpha_88 = alpha88(volume,Open,low,high,close) +alpha_92 = alpha92(volume,high,low,close,Open) +alpha_94 = alpha94(volume,vwap) +alpha_95 = alpha95(volume,high,low,Open) +alpha_96 = alpha96(volume,vwap,close) +alpha_98 = alpha98(volume,Open,vwap) +alpha_99 = alpha99(volume,high,low) +alpha_100 = alpha41(high,low,vwap) +alpha_101 = alpha101(close,Open,high,low) + +alpha_48 = alpha48(close,ind) # 这些因子涉及行业中性化,计算时间较长 +alpha_58 = alpha58(vwap,volume,ind) +alpha_59 = alpha59(vwap,volume,ind) +alpha_63 = alpha63(volume,close,vwap,Open,ind) +alpha_67 = alpha67(volume,vwap,high,ind) +alpha_69 = alpha69(volume,vwap,ind,close) +alpha_70 = alpha70(close,ind,vwap) +alpha_76 = alpha76(volume,vwap,low,ind) +alpha_79 = alpha79(volume,close,Open,ind,vwap) +alpha_80 = alpha80(Open,high,ind) +alpha_82 = alpha82(Open,volume,ind) +alpha_87 = alpha87(volume,close,vwap) +alpha_89 = alpha89(low,vwap,ind) +alpha_90 = alpha90(volume,close,ind,low) +alpha_91 = alpha91(close,ind,volume,vwap) +alpha_93 = alpha93(vwap,ind,volume,close) +alpha_97 = alpha97(volume,low,vwap,ind) +alpha_100 = alpha100(volume,close,low,high,ind) + +# 因子放入列表 +data_alpha = [alpha_1,alpha_2,alpha_3,alpha_4,alpha_5,alpha_6,alpha_7,alpha_8,alpha_9,alpha_10, + alpha_11,alpha_12,alpha_13,alpha_14,alpha_15,alpha_16,alpha_17,alpha_18,alpha_19,alpha_20, + alpha_21,alpha_22,alpha_23,alpha_24,alpha_25,alpha_26,alpha_27,alpha_28,alpha_29,alpha_30, + alpha_31,alpha_32,alpha_33,alpha_34,alpha_35,alpha_36,alpha_37,alpha_38,alpha_39,alpha_40, + alpha_41,alpha_42,alpha_43,alpha_44,alpha_45,alpha_46,alpha_47,alpha_48,alpha_49,alpha_50, + alpha_51,alpha_52,alpha_53,alpha_54,alpha_55,alpha_56,alpha_57,alpha_58,alpha_59,alpha_60, + alpha_61,alpha_62,alpha_63,alpha_64,alpha_65,alpha_66,alpha_67,alpha_68,alpha_69,alpha_70, + alpha_71,alpha_72,alpha_73,alpha_74,alpha_75,alpha_76,alpha_77,alpha_78,alpha_79,alpha_80, + alpha_81,alpha_82,alpha_83,alpha_84,alpha_85,alpha_86,alpha_87,alpha_88,alpha_89,alpha_90, + alpha_91,alpha_92,alpha_93,alpha_94,alpha_95,alpha_96,alpha_97,alpha_98,alpha_99,alpha_100,alpha_101] + +# 由于一些因子应用前几个月的数据进行计算,因此初始时期因子为错误值,所以取两年保留一年 +for i in range(len(data_alpha)): + data_alpha[i] = data_alpha[i].iloc[245:] # 243,245,244,244,244/这些数字为某年交易日数量 +df_101 = pd.concat(data_alpha) # 合并各因子的数据 +df_101.to_csv('data/alpha.csv') # 储存数据至csv文件 + +## 提取数据并转换数据结构 +# 因子数据转化为时间+股票的双重索引格式 +def zhuanhuan(alpha_1,date,stocks,columns = ['alpha']): + alpha_year = alpha_1.fillna(value = 0) + alpha_year.set_index(date,inplace = True) + index = pd.MultiIndex.from_product([date,stocks],names = ['date', 'codes']) + df = pd.DataFrame(alpha_year.stack(),columns = columns) + alpha = pd.DataFrame(df.values,columns = columns,index = index) + return alpha + +date_list = ['2014-01-01','2015-01-01','2016-01-01','2017-01-01','2018-01-01','2019-05-30'] # 测试区间,每年更换一次股票池 +data_alpha = [] +div = 101 +# 从csv文件取出因子数据存进列表 +for i in range(5): + data_ = pd.read_csv('data/data_alpha_re'+str(i+1)+'.csv') + data_.drop(data_.columns[0], axis=1, inplace=True) + data_alpha.append(data_) +# 将之前合并的因子进行分割,并转换数据结构为双重索引,存进二维列表 +for i in range(5): + data = [] + df = data_alpha[i] + n = int(len(df)/div) + date = w.wsd('000001.SZ','close',date_list[i],date_list[i+1],period = 'D',usedf = True)[1].index + stocks = w.wset("sectorconstituent", "date="+date_list[i+1]+";windcode=000906.SH").Data[1] + for j in range(div): + d = zhuanhuan(df.iloc[n*j:n*(j+1)],date,stocks,columns = ['alpha'+str(j+1)]) + data.append(d) + data_alpha[i] = data +# 将各因子不同时期的数据进行合并,得到一维列表data存放各因子的双重索引可用数据 +data = [] +for j in range(div): + d = pd.concat([data_alpha[0][j],data_alpha[1][j],data_alpha[2][j],data_alpha[3][j],data_alpha[4][j]]) + data.append(d) diff --git a/wq101alphas/alpha101_code/03-单因子IC测试 b/wq101alphas/alpha101_code/03-单因子IC测试 new file mode 100644 index 0000000..92c00d4 --- /dev/null +++ b/wq101alphas/alpha101_code/03-单因子IC测试 @@ -0,0 +1,61 @@ +## 股票池筛选,可交易,非新股,非PT,ST,涨跌停的股票 +def get_stocks(trDate): + trDate = trDate.strftime('%Y-%m-%d') + stocks_800 = w.wset("sectorconstituent", "date="+trDate+";windcode=000906.SH").Data[1] + status = w.wss(stocks_800, "trade_status,maxupordown,riskwarning,ipo_date", tradeDate=trDate, usedf=True)[1] + date_least=w.tdaysoffset(-6,trDate,'Period=M').Data[0][0] + trade_codes=list(status[(status['TRADE_STATUS']=='交易')&(status['IPO_DATE']<=date_least)&(status['MAXUPORDOWN']==0)&(status['RISKWARNING']=='否')].index) + return trade_codes +trade_d = w.tdays("2014-01-02", "2019-05-30", Period='M',usedf=True).Data[0] +stock_valid = [] +for i in range(len(trade_d)): + stock_valid.append(get_stocks(trade_d[i])) +stock_valid_df = pd.DataFrame(stock_valid,index = trade_d) + +## 获取下期收益数据 +Period = 'M' +# 时间列表设置避免取到重复数据 +date_list = ['2014-01-02','2015-01-09','2016-01-08','2017-01-06','2018-01-05','2019-05-30'] +date_listd = ['2015-01-08','2016-01-07','2017-01-05','2018-01-04','2019-04-30'] +date_listw = ['2015-01-02','2016-01-01','2016-12-30','2017-12-29','2019-05-30'] +date_listm = ['2015-01-01','2016-01-01','2017-01-01','2018-01-01','2019-04-30'] +next_ret = [] +bench_date = [] # 之后分层测试可视化需要用到 +for i in range(5): + date = w.wsd('000001.SZ','close',date_list[i],date_listm[i],period = Period,usedf = True)[1].index + stocks = w.wset("sectorconstituent", "date="+date_listm[i]+";windcode=000906.SH").Data[1] + d1 = w.tdaysoffset(1, date[0], Period = Period,usedf=True).Data[0][0].strftime('%Y-%m-%d') # 时间往后推一个周期,并且格式转化为字符串 + d2 = w.tdaysoffset(1, date[-1],Period = Period, usedf=True).Data[0][0].strftime('%Y-%m-%d') + bench_date.append(d1) + bench_date.append(d2) + next_ret_ = w.wsd(stocks, "pct_chg", d1, d2, usedf=True, Period = Period)[1].fillna(value = 0) + f = lambda x: x/100 # 万矿收益率数据单位为100%,这里换算成小数 + next_ret_ = next_ret_.applymap(f) + next_ret.append(zhuanhuan(next_ret_,date,stocks,columns = ['NEXT_RET'])) # 转化下期收益数据为双重索引 +next_ret = pd.concat(next_ret) # 合并5年的下期收益数据 + +## IC测试 +def ic_fenxi(df,next_ret,alpha = ['alpha']): + d = list(next_ret.index.levels[0]) # 获取双索引中的日期索引 + ic_s = [] + df = df.fillna(value = 0) # 异常值填充为0 + for i in range(len(date_)): + stock_v = stock_valid_df.loc[d[i]].dropna().values # 获取当期有效股票池 + stock_v = list(set(stock_v) & set(df.loc[d[i]].index)) + dff = df.loc[d[i]].loc[stock_v] # 提取当期可用因子值和下期收益数据 + # dff = dff.sort_values(alpha,ascending=False).iloc[:round(len(dff)/10)] # 提取top组的数据分析 + ic_s.append(dff['NEXT_RET'].corr(dff[alpha],method='spearman')) # 计算因子值与下期收益的秩相关系数,并存进ic值列表 + ic_s = pd.Series(ic_s) # 列表转化为Series,从而能够计算各统计量 + rate = len(ic_s[ic_s>=0])/len(ic_s) # ic值大于0的比例 + IC_mean = ic_s.mean() # ic均值 + IC_std = ic_s.std() # ic标准差 + IC_IR = ic_s.mean()/ic_s.std() # ic_IR用来衡量因子有效性 + stats = [IC_mean,IC_std,IC_IR,rate] + return stats + +for i in range(len(data)): + d = list(next_ret.index.levels[0]) + lc = data[i].loc[d] # 根据调仓频率筛选数据 + lc['NEXT_RET'] = next_ret.NEXT_RET + list_ic = ic_fenxi(lc,next_ret,alpha = ['alpha'+str(i+1)]) # 计算IC统计量 + print(list_ic) diff --git a/wq101alphas/alpha101_code/04-单因子分层测试 b/wq101alphas/alpha101_code/04-单因子分层测试 new file mode 100644 index 0000000..f62061c --- /dev/null +++ b/wq101alphas/alpha101_code/04-单因子分层测试 @@ -0,0 +1,66 @@ +## 分层测试 +def return_fenxi(df,d,num,alpha = 'alpha'): + df.fillna(value = 0,inplace = True) + date_ = d + return_s = [] + for i in range(len(date_)): + stock_v = stock_valid_df.loc[d[i]].dropna().values + stock_v = list(set(stock_v) & set(df.loc[d[i]].index)) + dff = df.loc[d[i]].loc[stock_v] + x = dff[alpha] + if x.sum() != 0: # 筛选掉因子值异常期 + df_i = dff.sort_values(alpha) + return_list = [] + for j in range(num): + n1 = round(len(df_i)*j/num) + n2 = round(len(df_i)*(j+1)/num) + df_j = df_i.iloc[n1:n2] + return_j = df_j['NEXT_RET'].mean()+1 + return_list.append(return_j) + return_s.append(return_list) + x = np.array(return_s).T # 二维列表转化为二维数组转置 + return_s = [list(i) for i in x] + for i in range(num): + x = return_s[i] + for j in range(1,len(x)): + x[j] = x[j]*x[j-1] + return_s[i] = x + culmu = [re[-1] for re in return_s] + return culmu,return_s + +def fencengceshi(data,next_ret,num): + data_re = [] + data_re1 = [] + for i in range(len(data)): + lc = data[i] + #lc.fillna(value = 0,inplace = True) + d = list(next_ret.index.levels[0]) + lc = data[i].loc[d] + lc['NEXT_RET'] = next_ret.NEXT_RET + list_re1,list_re = return_fenxi(lc,d,num,alpha = data[i].columns[0]) + data_re.append(list_re) + data_re1.append(list_re1) + print(data_re1[i]) # 各因子最终各组累计收益 + return data_re + +df = fencengceshi(data,next_ret,num=20) # 各因子分组累计收益序列 +dff = fencengceshi(data,next_ret,num=1) # 计算等权基准线 + +## 各组收益时序图,top/middle/bottom +n = 1 +x = df[n-1] +y1 = x[0] +y2 = x[num/2] +y3 = x[-1] +d = list(next_ret.index.levels[0])[-len(y1):] +bench = dff[1][0][-len(y1):] + +plt.subplots(figsize=(15,5)) # 图的长宽设置 +plt.plot(d,y1,label='Group1') +plt.plot(d,y2,label='Group2') +plt.plot(d,y3,label='Group3') +plt.plot(d,bench,label='ZZ800') +plt.legend() +plt.title('alpha'+str(n)+' 分层测试(月)') +plt.xlabel('回测区间') +plt.ylabel("净值") diff --git a/wq101alphas/alpha101_code/05-回测相关处理函数 b/wq101alphas/alpha101_code/05-回测相关处理函数 new file mode 100644 index 0000000..96b15a5 --- /dev/null +++ b/wq101alphas/alpha101_code/05-回测相关处理函数 @@ -0,0 +1,135 @@ +from WindPy import * +import numpy as np +import pandas as pd +import numpy.linalg as la +import seaborn as sns +w.start() + +## 组合多因子 +lc = data.copy() +num_list = [42,44,36,15,4] +num_list = [i-1 for i in num_list] +m = [] +alpha_m = lc[num_list[0]].copy() +for i in num_list[1:]: + alpha_m['alpha'+str(i+1)] = lc[i]['alpha'+str(i+1)] + +## 因子数据预处理 +# 因子相关系数热力图 +fig=plt.figure(figsize=(10,6)) +relations= alpha_m.corr() +sns.heatmap(relations,annot=True,linewidths=0.05,linecolor='white',annot_kws={'size':8,'weight':'bold'}) + +# 中位数去极值 +def extreme_process_MAD(sample): # 输入的sample为时间截面的股票因子df数据 + factor_name = list(sample.columns) + for name in factor_name: + x = sample[name] + median = x.median() + MAD = abs(x - median).median() + x[x>(median+3*1.4826*MAD)] = median+3*1.4826*MAD + x[x<(median-3*1.4826*MAD)] = median-3*1.4826*MAD + sample[name] = x + return sample + +# 行业市值中性化 +def data_scale_neutral(sample,date): + stocks = list(sample.index) + ind=w.wss(stocks, "industry_citic","unit=1;tradeDate="+date+";industryType=1", usedf=True)[1] + Incap=w.wss(stocks, "val_lnmv","unit=1;tradeDate="+date+";industryType=1", usedf=True)[1] + data_med = pd.get_dummies(ind,columns=['INDUSTRY_CITIC']) # 生成0-1变量矩阵 + x = pd.concat([data_med,Incap],axis=1).dropna() + X= np.array(x) + sample = sample.loc[list(x.index)] + factor_name = list(sample.columns) + for name in factor_name: + y = np.array(sample[name]) + if la.matrix_rank(X.T.dot(X)) == X.shape[1]: + beta_ols = la.inv(X.T.dot(X)).dot(X.T).dot(y) # 最小二乘法计算拟合值 + residual = y - X.dot(beta_ols) # 取残差为中性化后的因子值 + else: + residual = y + sample[name] = residual + return sample + +# 标准化 +def standardize(sample): + factor_name = list(sample.columns) + for name in factor_name: + x = sample[name] + sample[name] = (x - np.mean(x))/(np.std(x)) + return sample + +# 数据预处理 +def data_process(sample,date): + sample = extreme_process_MAD(sample) + sample = data_scale_neutral(sample,date) + sample = standardize(sample) + return sample + +# 回测筛选股票池 +def get_stocks(trDate,A_stocks): + status = w.wss(A_stocks, "trade_status,maxupordown,riskwarning,ipo_date", tradeDate=trDate, usedf=True)[1] + date_least=w.tdaysoffset(-6,trDate,'Period=M').Data[0][0] + trade_codes=list(status[(status['TRADE_STATUS']=='交易')&(status['IPO_DATE']<=date_least)&(status['MAXUPORDOWN']==0)&(status['RISKWARNING']=='否')].index) + return trade_codes + +# 最大化历史ICIR加权/历史IC均值加权 +def IR_weight(bar_datetime_str,stocks,alpha_data): + Period="W" + begin_time = w.tdaysoffset(-12, bar_datetime_str, Period=Period, usedf=True).Data[0][0].strftime('%Y-%m-%d') + time_list = w.tdays(begin_time,bar_datetime_str,Period=Period, usedf=True).Data[0] + time_list = [time.strftime('%Y-%m-%d') for time in time_list] + IC_s = [] + IC = [] + next_ret = w.wsd(stocks, "pct_chg", begin_time, bar_datetime_str, usedf=True, Period = Period)[1].fillna(value = 0).iloc[1:] + for i in range(12): + factor = alpha_data.loc[time_list[i]].reset_index().set_index(['codes']).drop(columns = ['date']).loc[stocks] # 转化为股票单层索引 + factor_name = list(factor.columns) + ic_s = [] + for name in factor_name: + try: + ic_s.append(factor[name].corr(next_ret.iloc[i],method='spearman')) + except: + ic_s.append(factor[name].corr(next_ret.iloc[i-1],method='spearman')) + IC_s.append(ic_s) + IC_s = np.array(IC_s).T + W = np.cov(IC_s) + for i in range(len(IC_s)): + IC.append(IC_s[i].mean()) + IC_IR = np.dot(W,np.array(IC)) + return IC_IR # np.array(IC) + + # 最大化历史收益率加权 + def rate_weight(bar_datetime_str,stocks,alpha_data,num=10): + Period="W" + begin_time = w.tdaysoffset(-12, bar_datetime_str, Period=Period, usedf=True).Data[0][0].strftime('%Y-%m-%d') + time_list = w.tdays(begin_time,bar_datetime_str,Period=Period, usedf=True).Data[0] + time_list = [time.strftime('%Y-%m-%d') for time in time_list] + IC_s = [] + IC = [] + next_ret = w.wsd(stocks, "pct_chg", begin_time, bar_datetime_str, usedf=True, Period = Period)[1].fillna(value = 0).iloc[1:] + for i in range(12): + factor = alpha_data.loc[time_list[i]].reset_index().set_index(['codes']).drop(columns = ['date']).loc[stocks] + factor_name = list(factor.columns) + ic_s = [] + for name in factor_name: + g10 = list(factor.sort_values([name],ascending=False).iloc[:round(len(factor)/num)].index) + try: + ic_s = (next_ret.T.loc[g10]).T.iloc[i].mean() + except: + ic_s = (next_ret.T.loc[g10]).T.iloc[i-1].mean() + IC_s.append(ic_s) + IC_s = np.array(IC_s).T + for i in range(len(IC_s)): + IC.append(IC_s[i].mean()) + rate = np.array(IC) + return rate + + # 因子打分 +def factor_sum(sample,weight_list): + factor_name = list(sample.columns) + sample['alpha_sum'] = sample[factor_name[0]] * 0 + for i in range(len(factor_name)): + sample['alpha_sum'] = sample['alpha_sum'] + sample[factor_name[i]] * weight_list[i] + return sample diff --git a/wq101alphas/alpha101_code/06-有效因子回测 b/wq101alphas/alpha101_code/06-有效因子回测 new file mode 100644 index 0000000..12acbc9 --- /dev/null +++ b/wq101alphas/alpha101_code/06-有效因子回测 @@ -0,0 +1,68 @@ +from WindPy import * +from datetime import * +from WindAlgo import * +from scipy.stats import rankdata +import numpy as np +import pandas as pd +from datetime import datetime +import scipy.stats as stats +import numpy.linalg as la +w.start() + +alpha_data = alpha_m + +def initialize(context): + context.capital = 10000000 # 回测的初始资金 + context.securities = w.wset("sectorconstituent", "date=20140101;windcode=000906.SH").Data[1] + context.start_date = "20140104" # 回测开始时间 + context.end_date = "20190530" # 回测结束时间 + context.commission = 0.0003 # 手续费 + context.alpha_data = alpha_data + context.benchmark = '000906.SH' # 设置回测基准 + +def handle_data(bar_datetime, context, bar_data): + pass + +def my_schedule1(bar_datetime, context, bar_data): + bar_datetime_str = bar_datetime.strftime('%Y-%m-%d') + stock800 = w.wset("sectorconstituent", "date="+bar_datetime_str+";windcode=000906.SH").Data[1] + stocks = get_stocks(bar_datetime_str,stock800) # 获取筛选后的股票池 + ## 提取因子数据法 + data = context.alpha_data.loc[bar_datetime_str].reset_index().set_index(['codes']).drop(columns = ['date']) #提取因子数据并调整结构 + stock_v = list(set(stocks) & set(data.index)) + data = data.loc[stock_v].dropna(axis=0) # 筛选出有效股票池对应数据 + profit = w.wss(stock_v, "fa_oigr_ttm,pe_ttm", tradeDate=bar_datetime_str, usedf=True)[1] # 加入财务因子 + profit.index = data.index + data['1/PEG'] = profit['FA_OIGR_TTM']/profit['PE_TTM'] + data = data_process(data,bar_datetime_str) # 数据预处理 + weight = [] # 因子加权权重 + data = factor_sum(data,weight) # 因子打分 + ## 回测中计算法 +# start_time = w.tdaysoffset(-5, bar_datetime_str,usedf=True).Data[0][0].strftime('%Y-%m-%d') +# close = w.wsd(stocks,'close',start_time,bar_datetime_str,usedf = True)[1].reset_index().drop(columns = ['index']) +# vwap = w.wsd(stocks,'vwap',start_time,bar_datetime_str,usedf = True)[1].reset_index().drop(columns = ['index']) +# alpha = {'alpha':alpha42(vwap,close).iloc[-1]} +# data = pd.DataFrame(alpha,index=stocks) + + data = data.sort_values([data.columns.values[-1]],ascending=False) # 按打分大小排序 + code_list = list(data[:round(len(stocks)/5)].index) # 选出top组股票 + wa.change_securities(code_list) # 改变证券池 + context.securities = code_list + list_sell = list(wa.query_position().get_field('code')) # 获取当前仓位股票池 + for code in list_sell: + if code not in code_list: + volumn = wa.query_position()[code]['volume'] # 找到每个股票的持仓量 + res = wa.order(code,volumn,'sell',price='close', volume_check=False) + +def my_schedule2(bar_datetime, context,bar_data): + buy_code_list=list(set(context.securities)-(set(context.securities)-set(list(bar_data.get_field('code'))))) + list_now = list(wa.query_position().get_field('code')) # 获取当前仓位股票池 + for code in buy_code_list: + if code not in list_now: + res = wa.order_percent(code,1/len(buy_code_list),'buy',price='close', volume_check=False) # 等权买入 + +wa = BackTest(init_func = initialize, handle_data_func=handle_data) # 实例化回测对象 +wa.schedule(my_schedule1, "w", 0) # w表示在每周执行一次策略,0表示偏移,表示月初第一个交易日往后0天 +wa.schedule(my_schedule2, "w", 0) +res = wa.run(show_progress=True) # 调用run()函数开始回测,show_progress可用于指定是否显示回测净值曲线图 +nav_df = wa.summary('nav') # 获取回测结果,回测周期内每一天的组合净值 diff --git a/wq101alphas/alpha101_code/README.md b/wq101alphas/alpha101_code/README.md new file mode 100644 index 0000000..c56ba95 --- /dev/null +++ b/wq101alphas/alpha101_code/README.md @@ -0,0 +1,2 @@ +# alpha101 +基于万矿平台对alpha101因子进行测试并构造多因子策略 diff --git a/wq101alphas/wq101alpha.dos b/wq101alphas/wq101alpha.dos new file mode 100644 index 0000000..fcdf262 --- /dev/null +++ b/wq101alphas/wq101alpha.dos @@ -0,0 +1,1005 @@ +//alpha 1 +//rank(Ts_ArgMax(SignedPower((returns<0?stddev(returns,20):close), 2), 5))-0.5 + +def WQAlpha1(close){ + ts = mimax(pow(iif(ratios(close) - 1 < 0, mstd(ratios(close) - 1, 20), close), 2.0), 5) + return rowRank(X=ts, percent=true) - 0.5 +} + +//alpha 2 +//(-1 * correlation(rank(delta(log(volume), 2)), rank(((close - open) / open)), 6)) + +def WQAlpha2(vol, close, open){ + delta = log(vol) - log(mfirst(vol, 3)) + rank1 = rowRank(delta, percent=true) + rank2 = rowRank((close - open) \ open, percent=true) + return -mcorr(rank1, rank2, 6) +} + +//alpha 3 +//(-1 * correlation(rank(open), rank(volume), 10)) + +def WQAlpha3(vol, open){ + return -mcorr(rowRank(open, percent=true), rowRank(vol, percent=true), 10) +} + +//alpha 4 +//(-1 * Ts_Rank(rank(low), 9)) + +def WQAlpha4(low){ + return -mrank(rowRank(low, percent=true), true, 9) +} + +//alpha 5 +//(rank((open - (sum(vwap, 10) / 10))) * (-1 * abs(rank((close - vwap))))) + +def WQAlpha5(vwap, open, close){ + rank1 = rowRank((open - (msum(vwap, 10) \ 10)), percent=true) + rank2 = rowRank((close - vwap), percent=true) + return rank1 * (-1 * abs(rank2)) +} + +//alpha 6 +//(-1 * correlation(open, volume, 10)) + +def WQAlpha6(vol, open){ + return -mcorr(open, vol, 10) +} + +//alpha 7 +//((adv20 < volume) ? ((-1 * ts_rank(abs(delta(close, 7)), 60)) * sign(delta(close, 7))) : (-1 * 1)) + +def WQAlpha7(vol, close){ + delta = close - mfirst(close, 8) + return iif(mavg(vol, 20) < vol, -mrank(abs(delta), true, 60) * sign(delta), -1) +} + +//alpha 8 +//(-1 * rank(((sum(open, 5) * sum(returns, 5)) - delay((sum(open, 5) * sum(returns, 5)), 10)))) + +def WQAlpha8(open, close){ + sums = msum(open, 5) * msum((ratios(close) - 1), 5) + return -rowRank((sums - mfirst(sums, 11)), percent=true) +} + +//alpha 9 +// ((0 < ts_min(delta(close, 1), 5)) ? delta(close, 1) : ((ts_max(delta(close, 1), 5) < 0) ? delta(close, 1) : (-1 * delta(close, 1)))) + +def WQAlpha9(close){ + delta = close - mfirst(close, 2) + iffalse = iif(mmax(delta, 5) < 0, delta, -delta) + return iif(0 < mmin(delta, 5), delta, iffalse) +} + +//alpha 10 +//rank(((0 < ts_min(delta(close, 1), 4)) ? delta(close, 1) : ((ts_max(delta(close, 1), 4) < 0) ? delta(close, 1) : (-1 * delta(close, 1))))) + +def WQAlpha10(close){ + delta = close - mfirst(close, 2) + iffalse = iif(mmax(delta, 4) < 0, delta, -delta) + return rowRank(iif(0 < mmin(delta, 4), delta, iffalse), percent=true) +} + +//alpha 11 +//((rank(ts_max((vwap - close), 3)) + rank(ts_min((vwap - close), 3))) * rank(delta(volume, 3))) + +def WQAlpha11(vwap, vol, close){ + delta = vol - mfirst(vol, 4) + rank1 = rowRank(mmax((vwap - close), 3), percent=true) + rank2 = rowRank(mmin((vwap - close), 3), percent=true) + rank3 = rowRank(delta, percent=true) + return (rank1 + rank2) * rank3 +} + +//alpha 12 +//(sign(delta(volume, 1)) * (-1 * delta(close, 1))) + +def WQAlpha12(vol, close){ + return sign((vol - mfirst(vol, 2))) * (-1 * (close - mfirst(close, 2))) +} + +//alpha 13 +//(-1 * rank(covariance(rank(close), rank(volume), 5))) + +def WQAlpha13(vol, close){ + return -rowRank(mcovar(rowRank(close, percent=true), rowRank(vol, percent=true), 5), percent=true) +} + +//alpha 14 +//((-1 * rank(delta(returns, 3))) * correlation(open, volume, 10)) + +def WQAlpha14(vol, open, close){ + returns = ratios(close) - 1 + delta = returns - mfirst(returns, 4) + return -rowRank(delta, percent=true) * mcovar(open, vol, 10) +} + +//alpha 15 +//(-1 * sum(rank(correlation(rank(high), rank(volume), 3)), 3)) + +def WQAlpha15(vol, high){ + return -msum(rowRank(mcorr(rowRank(high, percent=true), rowRank(vol, percent=true), 3), percent=true), 3) +} + +//alpha 16 +//(-1 * rank(covariance(rank(high), rank(volume), 5))) + +def WQAlpha16(vol, high){ + return -rowRank(mcovar(rowRank(high, percent=true), rowRank(vol, percent=true), 5), percent=true) +} + +//alpha 17 +//(((-1 * rank(ts_rank(close, 10))) * rank(delta(delta(close, 1), 1))) * rank(ts_rank((volume / adv20), 5))) + +def WQAlpha17(vol, close){ + rank1 = rowRank(mrank(close, true, 10), percent=true) + rank2 = rowRank((close - mfirst(close, 2)) - mfirst((close - mfirst(close, 2)), 2), percent=true) + rank3 = rowRank(mrank((vol \ mavg(vol, 20)), true, 5), percent=true) + return -rank1 * rank2 * rank3 +} + +//alpha 18 +//(-1 * rank(((stddev(abs((close - open)), 5) + (close - open)) + correlation(close, open, 10)))) + +def WQAlpha18(close, open){ + return -rowRank((mstd(abs(close - open), 5) + close - open + mcorr(close, open, 10)), percent=true) +} + +//alpha 19 +//((-1 * sign(((close - delay(close, 7)) + delta(close, 7)))) * (1 + rank((1 + sum(returns, 250))))) + +def WQAlpha19(close){ + return -sign(close - mfirst(close, 8) + close - mfirst(close, 8)) * (1 + rowRank((1 + msum((ratios(close) - 1), 250)), percent=true)) +} + +//alpha 20 +//(((-1 * rank((open - delay(high, 1)))) * rank((open - delay(close, 1)))) * rank((open - delay(low, 1)))) + +def WQAlpha20(open, close, high, low){ + rank1 = rowRank((open - mfirst(high, 2)), percent=true) + rank2 = rowRank((open - mfirst(close, 2)), percent=true) + rank3 = rowRank((open - mfirst(low, 2)), percent=true) + return -rank1 * rank2 * rank3 +} + +//alpha 21 +//((((sum(close, 8) / 8) + stddev(close, 8)) < (sum(close, 2) / 2)) ? (-1 * 1) : (((sum(close, 2) / 2) < ((sum(close, 8) / 8) - stddev(close, 8))) ? 1 : (((1 < (volume / adv20)) || ((volume / adv20) == 1)) ? 1 : (-1 * 1)))) + +def WQAlpha21(close, vol){ + cond1 = (msum(close, 8) \ 8 + mstd(close, 8)) < (msum(close, 2) \ 2) + cond2 = (msum(close, 2) \ 2) < (msum(close, 8) \ 8 - mstd(close, 8)) + cond3 = (1 < (vol \ mavg(vol, 20))) || (vol \ mavg(vol, 20) == 1) + return iif(cond1, -1, iif(cond2, 1, iif(cond3, 1, -1))) +} + +//alpha 22 +//(-1 * (delta(correlation(high, volume, 5), 5) * rank(stddev(close, 20)))) + +def WQAlpha22(close, vol, high){ + delta = mcorr(high, vol, 5) - mfirst(mcorr(high, vol, 5), 6) + return -delta * rowRank(mstd(close, 20), percent=true) +} + +//alpha 23 +//(((sum(high, 20) / 20) < high) ? (-1 * delta(high, 2)) : 0) + +def WQAlpha23(high){ + delta = high - mfirst(high, 3) + return iif((msum(high, 20) \ 20 < high), -delta, 0) +} + +//alpha 24 +//((((delta((sum(close, 100) / 100), 100) / delay(close, 100)) < 0.05) || ((delta((sum(close, 100) / 100), 100) / delay(close, 100)) == 0.05)) ? (-1 * (close - ts_min(close, 100))) : (-1 * delta(close, 3))) + +def WQAlpha24(close){ + cond = (msum(close, 100) \ 100 - mfirst(msum(close, 100) \ 100, 101)) \ mfirst(close, 101) <= 0.05 + return iif(cond, -(close - mmin(close, 100)), -(close - mfirst(close, 4))) +} + +//alpha 25 +//rank(((((-1 * returns) * adv20) * vwap) * (high - close))) + +def WQAlpha25(close, vol, high, vwap){ + return rowRank((-(ratios(close) - 1) * mavg(vol, 20) * vwap * (high -close)), percent=true) +} + +//alpha 26 +//(-1 * ts_max(correlation(ts_rank(volume, 5), ts_rank(high, 5), 5), 3)) + +def WQAlpha26(vol, high){ + return -mmax(mcorr(mrank(vol, true, 5), mrank(high, true, 5), 5), 3) +} + +//alpha 27 +//((0.5 < rank((sum(correlation(rank(volume), rank(vwap), 6), 2) / 2.0))) ? (-1 * 1) : 1) + +def WQAlpha27(vol, vwap){ + return iif(0.5 < rowRank((msum(mcorr(rowRank(vol, percent=true), rowRank(vwap, percent=true), 6), 2) \ 2.0), percent=true), -1, 1) +} + +//alpha 28 +//scale(((correlation(adv20, low, 5) + ((high + low) / 2)) - close)) + +def WQAlpha28(vol, high, low, close){ + toscale = mcorr(mavg(vol, 20), low, 5) + ((high + low) \ 2) - close + return toscale \ rowSum(abs(toscale)) +} + +//alpha 29 +//(min(product(rank(rank(scale(log(sum(ts_min(rank(rank((-1 * rank(delta((close - 1), 5))))), 2), 1))))), 1), 5) + ts_rank(delay((-1 * returns), 6), 5)) + +def WQAlpha29(close){ + toscale = log(mmin(rowRank(rowRank((-rowRank((close - 1 - mfirst(close - 1, 6)), percent=true)), percent=true), percent=true), 2)) + scale = toscale \ rowSum(abs(toscale)) + ranks = rowRank(rowRank(scale, percent=true), percent=true) + return mmin(ranks, 5) + mrank(mfirst(-(ratios(close) - 1), 7), true, 5) +} + +//alpha 30 +//(((1.0 - rank(((sign((close - delay(close, 1))) + sign((delay(close, 1) - delay(close, 2)))) + sign((delay(close, 2) - delay(close, 3)))))) * sum(volume, 5)) / sum(volume, 20)) + +def WQAlpha30(vol, close){ + rank1 = rowRank(sign(close - mfirst(close, 2)) + sign(mfirst(close, 2) - mfirst(close, 3)) + sign(mfirst(close, 3) - mfirst(close, 4)), percent=true) + return (1.0 - rank1) * msum(vol, 5) \ msum(vol, 20) +} + +//alpha 31 +// ((rank(rank(rank(decay_linear((-1 * rank(rank(delta(close, 10)))), 10)))) + rank((-1 * delta(close, 3)))) + sign(scale(correlation(adv20, low, 12)))) + +def WQAlpha31(vol, close, low){ + decay_linear = mavg(-rowRank(rowRank((close - mfirst(close, 11)), percent=true), percent=true), 1..10) + rank1 = rowRank(rowRank(rowRank(decay_linear, percent=true), percent=true), percent=true) + rank2 = rowRank(-(close - mfirst(close, 4)), percent=true) + toscale = mcorr(mavg(vol, 20), low, 12) + scale = toscale \ rowSum(abs(toscale)) + return rank1 + rank2 + sign(scale) +} + + + +//alpha 32 +//(scale(((sum(close, 7) / 7) - close)) + (20 * scale(correlation(vwap, delay(close, 5), 230)))) + +def WQAlpha32(close, vwap){ + toscale1 = msum(close, 7) \ 7 - close + scale1 = toscale1 \ rowSum(abs(toscale1)) + toscale2 = mcorr(vwap, mfirst(close, 6), 230) + scale2 = toscale2 \ rowSum(abs(toscale2)) + return scale1 + 20 * scale2 +} + + + +//alpha 33 +//rank((-1 * ((1 - (open / close))^1))) + +def WQAlpha33(open, close){ + return rowRank((open \ close - 1), percent=true) +} + + + +//alpha 34 +//rank(((1 - rank((stddev(returns, 2) / stddev(returns, 5)))) + (1 - rank(delta(close, 1))))) + +def WQAlpha34(close){ + return rowRank(1 - rowRank((mstd(ratios(close) - 1, 2) \ mstd(ratios(close) - 1, 5)), percent=true) + 1 - rowRank((close - mfirst(close, 2)), percent=true), percent=true) +} + + + +//alpha 35 +//((Ts_Rank(volume, 32) * (1 - Ts_Rank(((close + high) - low), 16))) * (1 - Ts_Rank(returns, 32))) + +def WQAlpha35(vol, close, high, low){ + return mrank(vol, true, 32) * (1 - mrank((close + high - low), true, 16)) * (1 - mrank((ratios(close) - 1), true, 32)) +} + + + +//alpha 36 +//(((((2.21 * rank(correlation((close - open), delay(volume, 1), 15))) + (0.7 * rank((open - close)))) + (0.73 * rank(Ts_Rank(delay((-1 * returns), 6), 5)))) + rank(abs(correlation(vwap, adv20, 6)))) + (0.6 * rank((((sum(close, 200) / 200) - open) * (close - open))))) + +def WQAlpha36(vol, open, close, vwap){ + return 2.21 * rowRank(mcorr((close - open), mfirst(vol, 2), 15), percent=true) + 0.7 * rowRank((open - close), percent=true) + 0.73 * rowRank(mrank(mfirst(-(ratios(close) - 1), 7), true, 5), percent=true) + rowRank(abs(mcorr(vwap, mavg(vol, 20), 6)), percent=true) + 0.6 * rowRank((msum(close, 200) \ 200 - open) * (close - open), percent=true) +} + + + +//alpha 37 +//(rank(correlation(delay((open - close), 1), close, 200)) + rank((open - close))) + +def WQAlpha37(open, close){ + return rowRank(mcorr(mfirst((open - close), 2), close, 200), percent=true) + rowRank((open - close), percent=true) +} + + + +//alpha 38 +//((-1 * rank(Ts_Rank(close, 10))) * rank((close / open))) + +def WQAlpha38(open, close){ + return -rowRank(mrank(close, true, 10), percent=true) * rowRank((close \ open), percent=true) +} + + + +//alpha 39 +//((-1 * rank((delta(close, 7) * (1 - rank(decay_linear((volume / adv20), 9)))))) * (1 + rank(sum(returns, 250)))) + +def WQAlpha39(vol, close){ + decay_linear = mavg((vol \ mavg(vol, 20)), 1..9) + return -rowRank((close - mfirst(close, 8)) * (1 - rowRank(decay_linear, percent=true)), percent=true) * (1 + rowRank(msum(ratios(close - 1), 250), percent=true)) +} + + + +//alpha 40 +//((-1 * rank(stddev(high, 10))) * correlation(high, volume, 10)) + +def WQAlpha40(vol, high){ + return -rowRank(mstd(high, 10), percent=true) * mcorr(high, vol, 10) +} + +//alpha 41 +//(((high * low)^0.5) - vwap) + +def WQAlpha41(high, low, vwap){ + return pow(high * low, 0.5) - vwap +} + +//alpha 42 +//(rank((vwap - close)) / rank((vwap + close))) + +def WQAlpha42(vwap, close){ + return rowRank((vwap - close), percent=true) \ rowRank((vwap + close), percent=true) +} + + + +//alpha 43 +//(ts_rank((volume / adv20), 20) * ts_rank((-1 * delta(close, 7)), 8)) + +def WQAlpha43(vol, close){ + return mrank((vol \ mavg(vol, 20)), true, 20) * mrank(-(close - mfirst(close, 8)), true, 8) +} + + + +//alpha 44 +//(-1 * correlation(high, rank(volume), 5)) + +def WQAlpha44(vol, high){ + return -mcorr(high, rowRank(vol, percent=true), 5) +} + + + +//alpha 45 +//(-1 * ((rank((sum(delay(close, 5), 20) / 20)) * correlation(close, volume, 2)) * rank(correlation(sum(close, 5), sum(close, 20), 2)))) + +def WQAlpha45(vol, close){ + return -rowRank(msum(mfirst(close, 6), 20) \ 20, percent=true) * mcorr(close, vol, 2) * rowRank(mcorr(msum(close, 5), msum(close, 20), 2), percent=true) +} + + + +//alpha 46 +//((0.25 < (((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10))) ? (-1 * 1) : (((((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10)) < 0) ? 1 : ((-1 * 1) * (close - delay(close, 1))))) + +def WQAlpha46(close){ + cond = (mfirst(close, 21) - mfirst(close, 11)) \ 10 - (mfirst(close, 11) - close) \ 10 + return iif(0.25 < cond, -1, iif(cond < 0, 1, (mfirst(close, 2) - close))) +} + + + +//alpha 47 +//((((rank((1 / close)) * volume) / adv20) * ((high * rank((high - close))) / (sum(high, 5) / 5))) - rank((vwap - delay(vwap, 5)))) + +def WQAlpha47(vol, close, high, vwap){ + return rowRank(1 \ close, percent=true) * vol \ mavg(vol, 20) * (high * rowRank(high - close, percent=true) \ (msum(high, 5) \ 5)) - rowRank(vwap - mfirst(vwap, 6), percent=true) +} + + + +//alpha 49 +//(((((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10)) < (-1 * 0.1)) ? 1 : ((-1 * 1) * (close - delay(close, 1)))) + +def WQAlpha49(close){ + cond = ((mfirst(close, 21) - mfirst(close, 11)) \ 10 - (mfirst(close, 11) - close) \ 10) < -0.1 + return iif(cond, 1, mfirst(close, 2) - close) +} + + + +//alpha 50 +//(-1 * ts_max(rank(correlation(rank(volume), rank(vwap), 5)), 5)) + +def WQAlpha50(vol, vwap){ + return -mmax(rowRank(mcorr(rowRank(vol, percent=true), rowRank(vwap, percent=true), 5), percent=true), 5) +} + + + +//alpha 51 +//(((((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10)) < (-1 * 0.05)) ? 1 : ((-1 * 1) * (close - delay(close, 1)))) + +def WQAlpha51(close){ + cond = (mfirst(close, 21) - mfirst(close, 11)) \ 10 - (mfirst(close, 11) - close) \ 10 < -0.05 + return iif(cond, 1, -(close - mfirst(close, 2))) +} + + + +//alpha 52 +//((((-1 * ts_min(low, 5)) + delay(ts_min(low, 5), 5)) * rank(((sum(returns, 240) - sum(returns, 20)) / 220))) * ts_rank(volume, 5)) + +def WQAlpha52(vol, close, low){ + return (-mmin(low, 5) + mfirst(mmin(low, 5), 6)) * rowRank((msum(ratios(close) - 1, 240) - msum(ratios(close) - 1, 220)) \ 220, percent=true) * mrank(vol, true, 5) +} + + + +//alpha 53 +//(-1 * delta((((close - low) - (high - close)) / (close - low)), 9)) + +def WQAlpha53(close, high, low){ + return -(((close - low) - (high - close)) \ (close - low) - mfirst(((close - low) - (high - close)) \ (close - low), 10)) +} + + + +//alpha 54 +//((-1 * ((low - close) * (open^5))) / ((low - high) * (close^5))) + +def WQAlpha54(open, close, high, low){ + return -(low - close) * pow(open, 5) \ ((low - high) * pow(close, 5)) +} + + + +//alpha 55 +//(-1 * correlation(rank(((close - ts_min(low, 12)) / (ts_max(high, 12) - ts_min(low, 12)))), rank(volume), 6)) + +def WQAlpha55(vol, close, high, low){ + return -mcorr(rowRank((close - mmin(low, 12)) \ (mmax(high, 12) - mmin(low, 12)), percent=true), rowRank(vol, percent=true), 6) +} + + + +//alpha 57 +//(0 - (1 * ((close - vwap) / decay_linear(rank(ts_argmax(close, 30)), 2)))) + +def WQAlpha57(close, vwap){ + return -(close - vwap) \ mavg(rowRank(mimax(close, 30), percent=true), 1..2) +} + + + +//alpha 60 +//(0 - (1 * ((2 * scale(rank(((((close - low) - (high - close)) / (high - low)) * volume)))) - scale(rank(ts_argmax(close, 10)))))) + +def WQAlpha60(vol, close, high, low){ + toscale1 = rowRank(((close - low) - (high - close)) \ (high - low) * vol, percent=true) + scale1 = toscale1 \ rowSum(abs(toscale1)) + toscale2 = rowRank(mimax(close, 10), percent=true) + scale2 = toscale2 \ rowSum(abs(toscale2)) + return -(2 * scale1 - scale2) +} + + + +//alpha 61 +//(rank((vwap - ts_min(vwap, 16.1219))) < rank(correlation(vwap, adv180, 17.9282))) + +def WQAlpha61(vol, vwap){ + return rowRank(vwap - mmin(vwap, 16), percent=true) < rowRank(mcorr(vwap, mavg(vol, 180), 18), percent=true) +} + + + +//alpha 62 +//((rank(correlation(vwap, sum(adv20, 22.4101), 9.91009)) < rank(((rank(open) + rank(open)) < (rank(((high + low) / 2)) + rank(high))))) * -1) + +def WQAlpha62(vol, vwap, open, high, low){ + return (rowRank(mcorr(vwap, msum(mavg(vol, 20), 22), 10), percent=true) < rowRank((rowRank(open, percent=true) + rowRank(open, percent=true)) < (rowRank((high + low) \ 2, percent=true) + rowRank(high, percent=true)), percent=true)) * (-1) +} + + + +//alpha 64 +//((rank(correlation(sum(((open * 0.178404) + (low * (1 - 0.178404))), 12.7054), sum(adv120, 12.7054), 16.6208)) < rank(delta(((((high + low) / 2) * 0.178404) + (vwap * (1 - 0.178404))), 3.69741))) * -1) + +def WQAlpha64(vol, vwap, open, high, low){ + rank1 = rowRank(mcorr(msum(open * 0.178404 + low * (1 - 0.178404), 13), msum(mavg(vol, 120), 13), 17), percent=true) + deltax = (high + low) \ 2 * 0.178404 + vwap * (1 - 0.178404) + rank2 = rowRank(deltax - mfirst(deltax, 5), percent=true) + return (rank1 < rank2) * (-1) +} + + + +//alpha 65 +//((rank(correlation(((open * 0.00817205) + (vwap * (1 - 0.00817205))), sum(adv60, 8.6911), 6.40374)) < rank((open - ts_min(open, 13.635)))) * -1) + +def WQAlpha65(vol, vwap, open){ + rank1 = rowRank(mcorr((open * 0.00817205 + vwap * (1 - 0.00817205)), msum(mavg(vol, 60), 9), 6), percent=true) + rank2 = rowRank(open - mmin(open, 14), percent=true) + return (rank1 < rank2) * (-1) +} + + + +//alpha 66 +//((rank(decay_linear(delta(vwap, 3.51013), 7.23052)) + Ts_Rank(decay_linear(((((low * 0.96633) + (low * (1 - 0.96633))) - vwap) / (open - ((high + low) / 2))), 11.4157), 6.72611)) * -1) + +def WQAlpha66(vwap, high, low, open){ + return (rowRank(mavg(vwap - mfirst(vwap, 5), 1..7), percent=true) + mrank(mavg((low - vwap) \ (open - (high - low) \ 2), 1..11), true, 11)) * (-1) +} + + + +//alpha 68 +//((Ts_Rank(correlation(rank(high), rank(adv15), 8.91644), 13.9333) < rank(delta(((close * 0.518371) + (low * (1 - 0.518371))), 1.06157))) * -1) + +def WQAlpha68(vol, close, high, low){ + rank1 = mrank(mcorr(rowRank(high, percent=true), rowRank(mavg(vol, 15), percent=true), 9), true, 14) + deltax = close * 0.518371 + low * (1 - 0.518371) + rank2 = rowRank(deltax - mfirst(deltax, 2), percent=true) + return (rank1 < rank2) * (-1) +} + + + +//alpha 71 +//max(Ts_Rank(decay_linear(correlation(Ts_Rank(close, 3.43976), Ts_Rank(adv180, 12.0647), 18.0175), 4.20501), 15.6948), Ts_Rank(decay_linear((rank(((low + open) - (vwap + vwap)))^2), 16.4662), 4.4388)) + +def WQAlpha71(vol, vwap, close, open, low){ + decay_linear1 = mavg(mcorr(mrank(close, true, 3), mrank(mavg(vol, 180), true, 12), 18), 1..4) + rank1 = mrank(decay_linear1, true, 16) + decay_linear2 = mavg(pow(rowRank(low + open - (vwap + vwap), percent=true), 2), 1..16) + rank2 = mrank(decay_linear2, true, 4) + return max(rank1, rank2) +} + + + +//alpha 72 +//(rank(decay_linear(correlation(((high + low) / 2), adv40, 8.93345), 10.1519)) / rank(decay_linear(correlation(Ts_Rank(vwap, 3.72469), Ts_Rank(volume, 18.5188), 6.86671), 2.95011))) + +def WQAlpha72(vol, vwap, high, low){ + rank1 = rowRank(mavg(mcorr((high + low) \ 2, mavg(vol, 40), 9), 1..10), percent=true) + rank2 = rowRank(mavg(mcorr(mrank(vwap, true, 4), mrank(vol, true, 19), 7), 1..3), percent=true) + return rank1 \ rank2 +} + + + +//alpha 73 +//(max(rank(decay_linear(delta(vwap, 4.72775), 2.91864)), Ts_Rank(decay_linear(((delta(((open * 0.147155) + (low * (1 - 0.147155))), 2.03608) / ((open * 0.147155) + (low * (1 - 0.147155)))) * -1), 3.33829), 16.7411)) * -1) + +def WQAlpha73(vwap, open, low){ + rank1 = rowRank(mavg(vwap - mfirst(vwap, 6), 1..3), percent=true) + deltax = open * 0.147155 + low * (1 - 0.147155) + delta = deltax - mfirst(deltax, 3) + rank2 = mrank(mavg(delta \ deltax * (-1), 1..3), true, 17) + return max(rank1, rank2) * (-1) +} + + + +//alpha 74 +//((rank(correlation(close, sum(adv30, 37.4843), 15.1365)) < rank(correlation(rank(((high * 0.0261661) + (vwap * (1 - 0.0261661)))), rank(volume), 11.4791))) * -1) + +def WQAlpha74(vol, vwap, close, high){ + rank1 = rowRank(mcorr(close, msum(mavg(vol, 30), 37), 15), percent=true) + rank2 = rowRank(mcorr(rowRank(rowRank(high * 0.0261661 + vwap * (1 - 0.0261661), percent=true), percent=true), rowRank(vol, percent=true), 11), percent=true) + return (rank1 < rank2) * (-1) +} + + + +//alpha 75 +//(rank(correlation(vwap, volume, 4.24304)) < rank(correlation(rank(low), rank(adv50), 12.4413))) + +def WQAlpha75(vol, vwap, low){ + return rowRank(mcorr(vwap, vol, 4), percent=true) < rowRank(mcorr(rowRank(low, percent=true), rowRank(mavg(vol, 50), percent=true), 12), percent=true) +} + + + +//alpha 77 +//min(rank(decay_linear(((((high + low) / 2) + high) - (vwap + high)), 20.0451)), rank(decay_linear(correlation(((high + low) / 2), adv40, 3.1614), 5.64125))) + +def WQAlpha77(vol, vwap, high, low){ + rank1 = rowRank(mavg((high + low) \ 2 + high - (vwap + high), 1..20), percent=true) + rank2 = rowRank(mavg(mcorr((high + low) \ 2, mavg(vol, 40), 3), 1..6), percent=true) + return min(rank1, rank2) +} + + + +//alpha 78 +//(rank(correlation(sum(((low * 0.352233) + (vwap * (1 - 0.352233))), 19.7428), sum(adv40, 19.7428), 6.83313))^rank(correlation(rank(vwap), rank(volume), 5.77492))) + +def WQAlpha78(vol, vwap, low){ + rank1 = rowRank(mcorr(msum(low * 0.352233 + vwap * (1 - 0.352233), 20), msum(mavg(vol, 40), 20), 7), percent=true) + rank2 = rowRank(mcorr(rowRank(vwap, percent=true), rowRank(vol, percent=true), 6), percent=true) + return pow(rank1, rank2) +} + + + +//alpha 81 +//((rank(Log(product(rank((rank(correlation(vwap, sum(adv10, 49.6054), 8.47743))^4)), 14.9655))) < rank(correlation(rank(vwap), rank(volume), 5.07914))) * -1) + +def WQAlpha81(vol, vwap){ + rank1 = rowRank(log(mprod(rowRank(pow(rowRank(mcorr(vwap, msum(mavg(vol, 10), 49), 8), percent=true), 4), percent=true), 15)), percent=true) + rank2 = rowRank(mcorr(rowRank(vwap, percent=true), rowRank(vol, percent=true), 5), percent=true) + return (rank1 < rank2) * (-1) +} + + + +//alpha 83 +//((rank(delay(((high - low) / (sum(close, 5) / 5)), 2)) * rank(rank(volume))) / (((high - low) / (sum(close, 5) / 5)) / (vwap - close))) + +def WQAlpha83(vol, vwap, close, high, low){ + return rowRank(mfirst((high - low) \ (msum(close, 5) \ 5), 3), percent=true) * rowRank(rowRank(vol, percent=true), percent=true) \ (((high - low) \ (msum(close, 5) \ 5)) \ (vwap - close)) +} + + + +//alpha 84 +//SignedPower(Ts_Rank((vwap - ts_max(vwap, 15.3217)), 20.7127), delta(close, 4.96796)) + +def WQAlpha84(vwap, close){ + return pow(mrank(vwap - mmax(vwap, 15), true, 20), close - mfirst(close, 6)) +} + + + +//alpha 85 +//(rank(correlation(((high * 0.876703) + (close * (1 - 0.876703))), adv30, 9.61331))^rank(correlation(Ts_Rank(((high + low) / 2), 3.70596), Ts_Rank(volume, 10.1595), 7.11408))) + +def WQAlpha85(vol, close, high, low){ + rank1 = rowRank(mcorr(high * 0.876703 + close * (1 - 0.876703), mavg(vol, 30), 10), percent=true) + rank2 = rowRank(mcorr(mrank((high + low) \ 2, true, 4), mrank(vol, true, 10), 7), percent=true) + return pow(rank1, rank2) +} + + + +//alpha 86 +//((Ts_Rank(correlation(close, sum(adv20, 14.7444), 6.00049), 20.4195) < rank(((open + close) - (vwap + open)))) * -1) + +def WQAlpha86(vol, vwap, open, close){ + rank1 = mrank(mcorr(close, msum(mavg(vol, 20), 15), 6), true, 20) + rank2 = rowRank(open + close - (vwap + open), percent=true) + return (rank1 < rank2) * (-1) +} + + + +//alpha 88 +//min(rank(decay_linear(((rank(open) + rank(low)) - (rank(high) + rank(close))), 8.06882)), Ts_Rank(decay_linear(correlation(Ts_Rank(close, 8.44728), Ts_Rank(adv60, 20.6966), 8.01266), 6.65053), 2.61957)) + +def WQAlpha88(vol, open, close, high, low){ + rank1 = rowRank(mavg(rowRank(open, percent=true) + rowRank(low, percent=true) - (rowRank(high, percent=true) + rowRank(close, percent=true)), 1..8), percent=true) + rank2 = mrank(mavg(mcorr(mrank(close, true, 8), mrank(mavg(vol, 60), true, 21), 8), 1..7), true, 3) + return min(rank1, rank2) +} + + + +//alpha 92 +//min(Ts_Rank(decay_linear(((((high + low) / 2) + close) < (low + open)), 14.7221), 18.8683), Ts_Rank(decay_linear(correlation(rank(low), rank(adv30), 7.58555), 6.94024), 6.80584)) + +def WQAlpha92(vol, open, close, high, low){ + rank1 = mrank(mavg(((high + low) \ 2 + close) < (low + open), 1..15), true, 19) + rank2 = mrank(mavg(mcorr(rowRank(low, percent=true), rowRank(mavg(vol, 30), percent=true), 8), 1..7), true, 7) + return min(rank1, rank2) +} + + + +//alpha 94 +//((rank((vwap - ts_min(vwap, 11.5783)))^Ts_Rank(correlation(Ts_Rank(vwap, 19.6462), Ts_Rank(adv60, 4.02992), 18.0926), 2.70756)) * -1) + +def WQAlpha94(vol, vwap){ + rank1 = rowRank(vwap - mmin(vwap, 12), percent=true) + rank2 = mrank(mcorr(mrank(vwap, true, 20), mrank(mavg(vol, 60), true, 4), 18), true, 3) + return pow(rank1, rank2) * (-1) +} + + + +//alpha 95 +//(rank((open - ts_min(open, 12.4105))) < Ts_Rank((rank(correlation(sum(((high + low) / 2), 19.1351), sum(adv40, 19.1351), 12.8742))^5), 11.7584)) + +def WQAlpha95(vol, open, high, low){ + rank1 = rowRank(open - mmin(open, 12), percent=true) + rank2 = mrank(pow(rowRank(mcorr(msum((high + low) \ 2, 19), msum(mavg(vol, 40), 19), 13), percent=true), 5), true, 12) + return rank1 < rank2 +} + + + +//alpha 96 +//(max(Ts_Rank(decay_linear(correlation(rank(vwap), rank(volume), 3.83878), 4.16783), 8.38151), Ts_Rank(decay_linear(Ts_ArgMax(correlation(Ts_Rank(close, 7.45404), Ts_Rank(adv60, 4.13242), 3.65459), 12.6556), 14.0365), 13.4143)) * -1) + +def WQAlpha96(vol, vwap, close){ + rank1 = mrank(mavg(mcorr(rowRank(vwap, percent=true), rowRank(vol, percent=true), 4), 1..4), true, 8) + rank2 = mrank(mavg(mimax(mcorr(mrank(close, true, 7), mrank(mavg(vol, 60), true, 4), 4), 13), 1..14), true, 13) + return max(rank1, rank2) * (-1) +} + + + +//alpha 98 +//(rank(decay_linear(correlation(vwap, sum(adv5, 26.4719), 4.58418), 7.18088)) - rank(decay_linear(Ts_Rank(Ts_ArgMin(correlation(rank(open), rank(adv15), 20.8187), 8.62571), 6.95668), 8.07206))) + +def WQAlpha98(vwap, open, vol){ + return rowRank(X=mavg(mcorr(vwap, msum(mavg(vol, 5), 26), 5), 1..7), percent=true) - rowRank(X=mavg(mrank(9 - mimin(mcorr(rowRank(X=open, percent=true), rowRank(X=mavg(vol, 15), percent=true), 21), 9), true, 7), 1..8), percent=true) +} + + + +//alpha 99 +//((rank(correlation(sum(((high + low) / 2), 19.8975), sum(adv60, 19.8975), 8.8136)) < rank(correlation(low, volume, 6.28259))) * -1) + +def WQAlpha99(vol, high, low){ + rank1 = rowRank(mcorr(msum((high + low) \ 2, 20), msum(mavg(vol, 60), 20), 9), percent=true) + rank2 = rowRank(mcorr(low, vol, 6), percent=true) + return (rank1 < rank2) * (-1) +} + + + +//alpha 101 +//((close - open) / ((high - low) + .001)) + +def WQAlpha101(close, open, high, low){ + return ((close - open) \ (high - low + 0.001)); +} + + + +//2. Factors with industry classification information: +//The calculation process includes industry neutralization and requires complex operations such as context by. +//These factors take panel data as parameters and return panel data. +//Industry classification standards are not uniform. In order to facilitate generalization, we make certain adjustments to the formula. +//In this module, levels of classification are ignored; instead calculations applies directly to all bits of the industry classification. +//These factors are alpha 48,56,58,59,63,67,69,70,76,79,80,82,87,89,90,91,93,97,100. + + +//alpha 48 +//(indneutralize(((correlation(delta(close, 1), delta(delay(close, 1), 1), 250) * delta(close, 1)) / close), IndClass.subindustry) / sum(((delta(close, 1) / delay(close, 1))^2), 250)) + +def WQAlpha48(close, indclass){ + x = mcorr(close - mfirst(close, 2), mfirst(close, 2) - mfirst(mfirst(close, 2), 2), 250) * (close - mfirst(close, 2)) \ close + tmpsum = msum(pow((close - mfirst(close, 2)) \ mfirst(close, 2), 2), 250) + return byRow(contextby{demean, , indclass.row(0)}, x) \ tmpsum +} + + + +//alpha 56 +//(0 - (1 * (rank((sum(returns, 10) / sum(sum(returns, 2), 3))) * rank((returns * cap))))) + +def WQAlpha56(close, cap){ + tmp1 = msum(ratios(close) - 1, 10) \ msum(msum(ratios(close) - 1, 2), 3) + tmp2 = each(mul, (ratios(close) - 1), cap.row(0)) + return (-rowRank(tmp1) * rowRank(tmp2)) +} + + + +//alpha 58 +//(-1 * Ts_Rank(decay_linear(correlation(IndNeutralize(vwap, IndClass.sector), volume, 3.92795), 7.89291), 5.50322)) + +def WQAlpha58(vol, vwap, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, vwap) + return -mrank(mavg(mcorr(tmp, vol, 4), 1..8), true, 6) +} + + + +//alpha 59 +//(-1 * Ts_Rank(decay_linear(correlation(IndNeutralize(((vwap * 0.728317) + (vwap * (1 - 0.728317))), IndClass.industry), volume, 4.25197), 16.2289), 8.19648)) + +def WQAlpha59(vol, vwap, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, vwap * 0.728317 + vwap * (1 - 0.728317)) + return -mrank(mavg(mcorr(tmp, vol, 4), 1..16), true, 8) +} + + + +//alpha 63 +//((rank(decay_linear(delta(IndNeutralize(close, IndClass.industry), 2.25164), 8.22237)) - rank(decay_linear(correlation(((vwap * 0.318108) + (open * (1 - 0.318108))), sum(adv180, 37.2467), 13.557), 12.2883))) * -1) + +def WQAlpha63(vol, open, close, vwap, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, close) + decay1 = mavg(tmp - mfirst(tmp, 3), 1..8) + decay2 = mavg(mcorr(vwap * 0.318108 + open * (1 - 0.318108), msum(mavg(vol, 180), 37), 14), 1..12) + return ((rowRank(decay1, percent=true) - rowRank(decay2, percent=true)) * (-1)) +} + + + +//alpha 67 +//((rank((high - ts_min(high, 2.14593)))^rank(correlation(IndNeutralize(vwap, IndClass.sector), IndNeutralize(adv20, IndClass.subindustry), 6.02936))) * -1) + +def WQAlpha67(vol, high, vwap, indclass){ + tmp_vwap = byRow(contextby{demean, , indclass.row(0)}, vwap) + tmp_adv = byRow(contextby{demean, , indclass.row(0)}, mavg(vol, 20)) + tmpcorr = mcorr(tmp_vwap, tmp_adv, 6) + return (pow(rowRank((high - mmin(high, 2)), percent=true), rowRank(tmpcorr, percent=true)) * (-1)) +} + + + +//alpha 69 +//((rank(ts_max(delta(IndNeutralize(vwap, IndClass.industry), 2.72412), 4.79344))^Ts_Rank(correlation(((close * 0.490655) + (vwap * (1 - 0.490655))), adv20, 4.92416), 9.0615)) * -1) + +def WQAlpha69(vol, close, vwap, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, vwap) + tmpmax = mmax(tmp - mfirst(tmp, 4), 5) + trank = mrank(mcorr(close * 0.490655 + vwap * (1 - 0.490655), mavg(vol, 20), 5), true, 9) + return (pow(rowRank(tmpmax, percent=true), trank) * (-1)) +} + + + +//alpha 70 +//((rank(delta(vwap, 1.29456))^Ts_Rank(correlation(IndNeutralize(close, IndClass.industry), adv50, 17.8256), 17.9171)) * -1) + +def WQAlpha70(vol, close, vwap, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, close) + tmpdelta = vwap - mfirst(vwap, 2) + trank = mrank(mcorr(tmp, mavg(vol, 50), 18), true, 18) + return (pow(rowRank(tmpdelta, percent=true), trank) * (-1)) +} + + + +//alpha 76 +//(max(rank(decay_linear(delta(vwap, 1.24383), 11.8259)), Ts_Rank(decay_linear(Ts_Rank(correlation(IndNeutralize(low, IndClass.sector), adv81, 8.14941), 19.569), 17.1543), 19.383)) * -1) + +def WQAlpha76(vol, low, vwap, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, low) + decay = mavg(vwap - mfirst(vwap, 2), 1..12) + trank = mrank(mavg(mrank(mcorr(tmp, mavg(vol, 81), 8), true, 20), 1..17), true, 19) + tmprank = rowRank(decay, percent=true) + return (max(tmprank, trank) * (-1)) +} + + + +//alpha 79 +//(rank(delta(IndNeutralize(((close * 0.60733) + (open * (1 - 0.60733))), IndClass.sector), 1.23438)) < rank(correlation(Ts_Rank(vwap, 3.60973), Ts_Rank(adv150, 9.18637), 14.6644))) + +def WQAlpha79(vol, open, close, vwap, indclass){ + tmpavg = byRow(contextby{avg, , indclass.row(0)}, close * 0.60733 + open * (1 - 0.60733)) + delta = tmpavg - mfirst(tmpavg, 2) + tmpcorr = mcorr(mrank(vwap, true, 4), mrank(mavg(vol, 150), true, 9), 15) + return (rowRank(delta, percent=true) < rowRank(tmpcorr, percent=true)) +} + + + +//alpha 80 +//((rank(Sign(delta(IndNeutralize(((open * 0.868128) + (high * (1 - 0.868128))), IndClass.industry), 4.04545)))^Ts_Rank(correlation(high, adv10, 5.11456), 5.53756)) * -1) + +def WQAlpha80(vol, open, high, indclass){ + tmpavg = byRow(contextby{avg, , indclass.row(0)}, open * 0.868128 + high * (1 - 0.868128)) + signdelta = sign(tmpavg - mfirst(tmpavg, 5)) + trank = mrank(mcorr(high, mavg(vol, 10), 5), true, 6) + return pow(rowRank(signdelta, percent=true), trank) +} + + + +//alpha 82 +//(min(rank(decay_linear(delta(open, 1.46063), 14.8717)), Ts_Rank(decay_linear(correlation(IndNeutralize(volume, IndClass.sector), ((open * 0.634196) + (open * (1 - 0.634196))), 17.4842), 6.92131), 13.4283)) * -1) + + +def WQAlpha82(vol, open, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, vol) + decay = mavg(open - mfirst(open, 2), 1..15) + trank = mrank(mavg(mcorr(tmp, open * 0.634196 + open * (1 - 0.634196), 17), 1..7), true, 13) + return min(rowRank(decay, percent=true), trank) * (-1) +} + + + +//alpha 87 +//(max(rank(decay_linear(delta(((close * 0.369701) + (vwap * (1 - 0.369701))), 1.91233), 2.65461)), Ts_Rank(decay_linear(abs(correlation(IndNeutralize(adv81, IndClass.industry), close, 13.4132)), 4.89768), 14.4535)) * -1) + + +def WQAlpha87(vol, close, vwap, indclass){ + adv81 = mavg(vol, 81) + decay = mavg(close * 0.369701 + vwap * (1 - 0.369701) - mfirst(close * 0.369701 + vwap * (1 - 0.369701), 3), 1..3) + tmp = byRow(contextby{demean, , indclass.row(0)}, adv81) + trank = mrank(mavg(abs(mcorr(tmp, close, 13)), 1..5), true, 14) + return max(rowRank(decay, percent=true), trank) * (-1) +} + + + +//alpha 89 +//(Ts_Rank(decay_linear(correlation(((low * 0.967285) + (low * (1 - 0.967285))), adv10, 6.94279), 5.51607), 3.79744) - Ts_Rank(decay_linear(delta(IndNeutralize(vwap, IndClass.industry), 3.48158), 10.1466), 15.3012)) + +def WQAlpha89(vol, low, vwap, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, vwap) + return mrank(mavg(mcorr(low * 0.967285 + low * (1 - 0.967285), mavg(vol, 10), 7), 1..6), true, 4) - mrank(mavg(tmp- mfirst(tmp, 4), 1..10), true, 15) +} + + + +//alpha 90 +//((rank((close - ts_max(close, 4.66719)))^Ts_Rank(correlation(IndNeutralize(adv40, IndClass.subindustry), low, 5.38375), 3.21856)) * -1) + +def WQAlpha90(vol, low, close, indclass){ + adv40 = mavg(vol, 40) + tmpclose = close - mmax(close, 5) + tmp = byRow(contextby{demean, , indclass.row(0)}, adv40) + trank = mrank(mcorr(tmp, low, 5), true, 3) + return (pow(rowRank(tmpclose, percent=true), trank) * (-1)) +} + + + +//alpha 91 +//((Ts_Rank(decay_linear(decay_linear(correlation(IndNeutralize(close, IndClass.industry), volume, 9.74928), 16.398), 3.83219), 4.8667) - rank(decay_linear(correlation(vwap, adv30, 4.01303), 2.6809))) * -1) + +def WQAlpha91(vol, close, vwap, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, close) + trank = mrank(mavg(mavg(mcorr(tmp, vol, 10), 1..16), 1..4), true, 5) + decay = mavg(mcorr(vwap, mavg(vol, 30), 4), 1..3) + return trank - rowRank(decay, percent=true) +} + + + +//alpha 93 +//(Ts_Rank(decay_linear(correlation(IndNeutralize(vwap, IndClass.industry), adv81, 17.4193), 19.848), 7.54455) / rank(decay_linear(delta(((close * 0.524434) + (vwap * (1 - 0.524434))), 2.77377), 16.2664))) + +def WQAlpha93(vol, close, vwap, indclass){ + tmp = byRow(contextby{demean, , indclass.row(0)}, vwap) + trank = mrank(mavg(mcorr(tmp, mavg(vol, 81), 17), 1..20), true, 8) + decay = mavg(close * 0.524434 + vwap * (1 - 0.524434) - mfirst(close * 0.524434 + vwap * (1 - 0.524434), 4), 1..16) + return trank \ float(rowRank(decay, percent=true)) +} + + + +//alpha 97 +//((rank(decay_linear(delta(IndNeutralize(((low * 0.721001) + (vwap * (1 - 0.721001))), IndClass.industry), 3.3705), 20.4523)) - Ts_Rank(decay_linear(Ts_Rank(correlation(Ts_Rank(low, 7.87871), Ts_Rank(adv60, 17.255), 4.97547), 18.5925), 15.7152), 6.71659)) * -1) + +def WQAlpha97(vol, low, vwap, indclass){ + tmp = low * 0.721001 + vwap * (1 - 0.721001) + tmpavg = byRow(contextby{avg, , indclass.row(0)}, tmp) + decay = mavg(tmp - tmpavg - mfirst(tmp - tmpavg, 4), 1..20) + trank = mrank(mavg(mrank(mcorr(mrank(low, true, 8), mrank(mavg(vol, 60), true, 17), 5), true, 19), 1..16), true, 7) + return (rowRank(decay, percent=true) - trank) * (-1) +} + + + +//alpha 100 +//(0 - (1 * (((1.5 * scale(indneutralize(indneutralize(rank(((((close - low) - (high - close)) / (high - low)) * volume)), IndClass.subindustry), IndClass.subindustry))) - scale(indneutralize((correlation(close, rank(adv20), 5) - rank(ts_argmin(close, 30))), IndClass.subindustry))) * (volume / adv20)))) + +def WQAlpha100(vol, high, low, close, indclass){ + tmprank = rowRank(((close - low - (high - close)) / (high - low) * vol), percent=true) + ind1 = byRow(contextby{demean, , indclass.row(0)}, tmprank) + ind2 = byRow(contextby{demean, , indclass.row(0)}, ind1) + adv20 = mavg(vol, 20) + argmin = mimin(close, 30) + rank1 = rowRank(adv20, percent=true) + rank2 = rowRank(argmin, percent=true) + x = mcorr(close, rank1, 5) - rank2 + ind3 = byRow(contextby{demean, , indclass.row(0)}, x) + return -(each(div, 1.5 * ind2, sum(abs(ind2))) - each(div, ind3, sum(abs(ind3))))*(vol \ adv20) +} diff --git a/wq101alphas/wq101alpha.json b/wq101alphas/wq101alpha.json new file mode 100644 index 0000000..4c28faa --- /dev/null +++ b/wq101alphas/wq101alpha.json @@ -0,0 +1,103 @@ +{ + "alpha 1": "rank(Ts_ArgMax(SignedPower((returns<0?stddev(returns,20):close), 2), 5))-0.5", + "alpha 2": "(-1 * correlation(rank(delta(log(volume), 2)), rank(((close - open) / open)), 6))", + "alpha 3": "(-1 * correlation(rank(open), rank(volume), 10))", + "alpha 4": "(-1 * Ts_Rank(rank(low), 9))", + "alpha 5": "(rank((open - (sum(vwap, 10) / 10))) * (-1 * abs(rank((close - vwap)))))", + "alpha 6": "(-1 * correlation(open, volume, 10))", + "alpha 7": "((adv20 < volume) ? ((-1 * ts_rank(abs(delta(close, 7)), 60)) * sign(delta(close, 7))) : (-1 * 1))", + "alpha 8": "(-1 * rank(((sum(open, 5) * sum(returns, 5)) - delay((sum(open, 5) * sum(returns, 5)), 10))))", + "alpha 9": " ((0 < ts_min(delta(close, 1), 5)) ? delta(close, 1) : ((ts_max(delta(close, 1), 5) < 0) ? delta(close, 1) : (-1 * delta(close, 1))))", + "alpha 10": "rank(((0 < ts_min(delta(close, 1), 4)) ? delta(close, 1) : ((ts_max(delta(close, 1), 4) < 0) ? delta(close, 1) : (-1 * delta(close, 1)))))", + "alpha 11": "((rank(ts_max((vwap - close), 3)) + rank(ts_min((vwap - close), 3))) * rank(delta(volume, 3)))", + "alpha 12": "(sign(delta(volume, 1)) * (-1 * delta(close, 1)))", + "alpha 13": "(-1 * rank(covariance(rank(close), rank(volume), 5)))", + "alpha 14": "((-1 * rank(delta(returns, 3))) * correlation(open, volume, 10))", + "alpha 15": "(-1 * sum(rank(correlation(rank(high), rank(volume), 3)), 3))", + "alpha 16": "(-1 * rank(covariance(rank(high), rank(volume), 5)))", + "alpha 17": "(((-1 * rank(ts_rank(close, 10))) * rank(delta(delta(close, 1), 1))) * rank(ts_rank((volume / adv20), 5)))", + "alpha 18": "(-1 * rank(((stddev(abs((close - open)), 5) + (close - open)) + correlation(close, open, 10))))", + "alpha 19": "((-1 * sign(((close - delay(close, 7)) + delta(close, 7)))) * (1 + rank((1 + sum(returns, 250)))))", + "alpha 20": "(((-1 * rank((open - delay(high, 1)))) * rank((open - delay(close, 1)))) * rank((open - delay(low, 1))))", + "alpha 21": "((((sum(close, 8) / 8) + stddev(close, 8)) < (sum(close, 2) / 2)) ? (-1 * 1) : (((sum(close, 2) / 2) < ((sum(close, 8) / 8) - stddev(close, 8))) ? 1 : (((1 < (volume / adv20)) || ((volume / adv20) == 1)) ? 1 : (-1 * 1))))", + "alpha 22": "(-1 * (delta(correlation(high, volume, 5), 5) * rank(stddev(close, 20))))", + "alpha 23": "(((sum(high, 20) / 20) < high) ? (-1 * delta(high, 2)) : 0)", + "alpha 24": "((((delta((sum(close, 100) / 100), 100) / delay(close, 100)) < 0.05) || ((delta((sum(close, 100) / 100), 100) / delay(close, 100)) == 0.05)) ? (-1 * (close - ts_min(close, 100))) : (-1 * delta(close, 3)))", + "alpha 25": "rank(((((-1 * returns) * adv20) * vwap) * (high - close)))", + "alpha 26": "(-1 * ts_max(correlation(ts_rank(volume, 5), ts_rank(high, 5), 5), 3))", + "alpha 27": "((0.5 < rank((sum(correlation(rank(volume), rank(vwap), 6), 2) / 2.0))) ? (-1 * 1) : 1)", + "alpha 28": "scale(((correlation(adv20, low, 5) + ((high + low) / 2)) - close))", + "alpha 29": "(min(product(rank(rank(scale(log(sum(ts_min(rank(rank((-1 * rank(delta((close - 1), 5))))), 2), 1))))), 1), 5) + ts_rank(delay((-1 * returns), 6), 5))", + "alpha 30": "(((1.0 - rank(((sign((close - delay(close, 1))) + sign((delay(close, 1) - delay(close, 2)))) + sign((delay(close, 2) - delay(close, 3)))))) * sum(volume, 5)) / sum(volume, 20))", + "alpha 31": " ((rank(rank(rank(decay_linear((-1 * rank(rank(delta(close, 10)))), 10)))) + rank((-1 * delta(close, 3)))) + sign(scale(correlation(adv20, low, 12))))", + "alpha 32": "(scale(((sum(close, 7) / 7) - close)) + (20 * scale(correlation(vwap, delay(close, 5), 230))))", + "alpha 33": "rank((-1 * ((1 - (open / close))^1)))", + "alpha 34": "rank(((1 - rank((stddev(returns, 2) / stddev(returns, 5)))) + (1 - rank(delta(close, 1)))))", + "alpha 35": "((Ts_Rank(volume, 32) * (1 - Ts_Rank(((close + high) - low), 16))) * (1 - Ts_Rank(returns, 32)))", + "alpha 36": "(((((2.21 * rank(correlation((close - open), delay(volume, 1), 15))) + (0.7 * rank((open - close)))) + (0.73 * rank(Ts_Rank(delay((-1 * returns), 6), 5)))) + rank(abs(correlation(vwap, adv20, 6)))) + (0.6 * rank((((sum(close, 200) / 200) - open) * (close - open)))))", + "alpha 37": "(rank(correlation(delay((open - close), 1), close, 200)) + rank((open - close)))", + "alpha 38": "((-1 * rank(Ts_Rank(close, 10))) * rank((close / open)))", + "alpha 39": "((-1 * rank((delta(close, 7) * (1 - rank(decay_linear((volume / adv20), 9)))))) * (1 + rank(sum(returns, 250))))", + "alpha 40": "((-1 * rank(stddev(high, 10))) * correlation(high, volume, 10))", + "alpha 41": "(((high * low)^0.5) - vwap)", + "alpha 42": "(rank((vwap - close)) / rank((vwap + close)))", + "alpha 43": "(ts_rank((volume / adv20), 20) * ts_rank((-1 * delta(close, 7)), 8))", + "alpha 44": "(-1 * correlation(high, rank(volume), 5))", + "alpha 45": "(-1 * ((rank((sum(delay(close, 5), 20) / 20)) * correlation(close, volume, 2)) * rank(correlation(sum(close, 5), sum(close, 20), 2))))", + "alpha 46": "((0.25 < (((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10))) ? (-1 * 1) : (((((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10)) < 0) ? 1 : ((-1 * 1) * (close - delay(close, 1)))))", + "alpha 47": "((((rank((1 / close)) * volume) / adv20) * ((high * rank((high - close))) / (sum(high, 5) / 5))) - rank((vwap - delay(vwap, 5))))", + "alpha 49": "(((((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10)) < (-1 * 0.1)) ? 1 : ((-1 * 1) * (close - delay(close, 1))))", + "alpha 50": "(-1 * ts_max(rank(correlation(rank(volume), rank(vwap), 5)), 5))", + "alpha 51": "(((((delay(close, 20) - delay(close, 10)) / 10) - ((delay(close, 10) - close) / 10)) < (-1 * 0.05)) ? 1 : ((-1 * 1) * (close - delay(close, 1))))", + "alpha 52": "((((-1 * ts_min(low, 5)) + delay(ts_min(low, 5), 5)) * rank(((sum(returns, 240) - sum(returns, 20)) / 220))) * ts_rank(volume, 5))", + "alpha 53": "(-1 * delta((((close - low) - (high - close)) / (close - low)), 9))", + "alpha 54": "((-1 * ((low - close) * (open^5))) / ((low - high) * (close^5)))", + "alpha 55": "(-1 * correlation(rank(((close - ts_min(low, 12)) / (ts_max(high, 12) - ts_min(low, 12)))), rank(volume), 6))", + "alpha 57": "(0 - (1 * ((close - vwap) / decay_linear(rank(ts_argmax(close, 30)), 2))))", + "alpha 60": "(0 - (1 * ((2 * scale(rank(((((close - low) - (high - close)) / (high - low)) * volume)))) - scale(rank(ts_argmax(close, 10))))))", + "alpha 61": "(rank((vwap - ts_min(vwap, 16.1219))) < rank(correlation(vwap, adv180, 17.9282)))", + "alpha 62": "((rank(correlation(vwap, sum(adv20, 22.4101), 9.91009)) < rank(((rank(open) + rank(open)) < (rank(((high + low) / 2)) + rank(high))))) * -1)", + "alpha 64": "((rank(correlation(sum(((open * 0.178404) + (low * (1 - 0.178404))), 12.7054), sum(adv120, 12.7054), 16.6208)) < rank(delta(((((high + low) / 2) * 0.178404) + (vwap * (1 - 0.178404))), 3.69741))) * -1)", + "alpha 65": "((rank(correlation(((open * 0.00817205) + (vwap * (1 - 0.00817205))), sum(adv60, 8.6911), 6.40374)) < rank((open - ts_min(open, 13.635)))) * -1)", + "alpha 66": "((rank(decay_linear(delta(vwap, 3.51013), 7.23052)) + Ts_Rank(decay_linear(((((low * 0.96633) + (low * (1 - 0.96633))) - vwap) / (open - ((high + low) / 2))), 11.4157), 6.72611)) * -1)", + "alpha 68": "((Ts_Rank(correlation(rank(high), rank(adv15), 8.91644), 13.9333) < rank(delta(((close * 0.518371) + (low * (1 - 0.518371))), 1.06157))) * -1)", + "alpha 71": "max(Ts_Rank(decay_linear(correlation(Ts_Rank(close, 3.43976), Ts_Rank(adv180, 12.0647), 18.0175), 4.20501), 15.6948), Ts_Rank(decay_linear((rank(((low + open) - (vwap + vwap)))^2), 16.4662), 4.4388))", + "alpha 72": "(rank(decay_linear(correlation(((high + low) / 2), adv40, 8.93345), 10.1519)) / rank(decay_linear(correlation(Ts_Rank(vwap, 3.72469), Ts_Rank(volume, 18.5188), 6.86671), 2.95011)))", + "alpha 73": "(max(rank(decay_linear(delta(vwap, 4.72775), 2.91864)), Ts_Rank(decay_linear(((delta(((open * 0.147155) + (low * (1 - 0.147155))), 2.03608) / ((open * 0.147155) + (low * (1 - 0.147155)))) * -1), 3.33829), 16.7411)) * -1)", + "alpha 74": "((rank(correlation(close, sum(adv30, 37.4843), 15.1365)) < rank(correlation(rank(((high * 0.0261661) + (vwap * (1 - 0.0261661)))), rank(volume), 11.4791))) * -1)", + "alpha 75": "(rank(correlation(vwap, volume, 4.24304)) < rank(correlation(rank(low), rank(adv50), 12.4413)))", + "alpha 77": "min(rank(decay_linear(((((high + low) / 2) + high) - (vwap + high)), 20.0451)), rank(decay_linear(correlation(((high + low) / 2), adv40, 3.1614), 5.64125)))", + "alpha 78": "(rank(correlation(sum(((low * 0.352233) + (vwap * (1 - 0.352233))), 19.7428), sum(adv40, 19.7428), 6.83313))^rank(correlation(rank(vwap), rank(volume), 5.77492)))", + "alpha 81": "((rank(Log(product(rank((rank(correlation(vwap, sum(adv10, 49.6054), 8.47743))^4)), 14.9655))) < rank(correlation(rank(vwap), rank(volume), 5.07914))) * -1)", + "alpha 83": "((rank(delay(((high - low) / (sum(close, 5) / 5)), 2)) * rank(rank(volume))) / (((high - low) / (sum(close, 5) / 5)) / (vwap - close)))", + "alpha 84": "SignedPower(Ts_Rank((vwap - ts_max(vwap, 15.3217)), 20.7127), delta(close, 4.96796))", + "alpha 85": "(rank(correlation(((high * 0.876703) + (close * (1 - 0.876703))), adv30, 9.61331))^rank(correlation(Ts_Rank(((high + low) / 2), 3.70596), Ts_Rank(volume, 10.1595), 7.11408)))", + "alpha 86": "((Ts_Rank(correlation(close, sum(adv20, 14.7444), 6.00049), 20.4195) < rank(((open + close) - (vwap + open)))) * -1)", + "alpha 88": "min(rank(decay_linear(((rank(open) + rank(low)) - (rank(high) + rank(close))), 8.06882)), Ts_Rank(decay_linear(correlation(Ts_Rank(close, 8.44728), Ts_Rank(adv60, 20.6966), 8.01266), 6.65053), 2.61957))", + "alpha 92": "min(Ts_Rank(decay_linear(((((high + low) / 2) + close) < (low + open)), 14.7221), 18.8683), Ts_Rank(decay_linear(correlation(rank(low), rank(adv30), 7.58555), 6.94024), 6.80584))", + "alpha 94": "((rank((vwap - ts_min(vwap, 11.5783)))^Ts_Rank(correlation(Ts_Rank(vwap, 19.6462), Ts_Rank(adv60, 4.02992), 18.0926), 2.70756)) * -1)", + "alpha 95": "(rank((open - ts_min(open, 12.4105))) < Ts_Rank((rank(correlation(sum(((high + low) / 2), 19.1351), sum(adv40, 19.1351), 12.8742))^5), 11.7584))", + "alpha 96": "(max(Ts_Rank(decay_linear(correlation(rank(vwap), rank(volume), 3.83878), 4.16783), 8.38151), Ts_Rank(decay_linear(Ts_ArgMax(correlation(Ts_Rank(close, 7.45404), Ts_Rank(adv60, 4.13242), 3.65459), 12.6556), 14.0365), 13.4143)) * -1)", + "alpha 98": "(rank(decay_linear(correlation(vwap, sum(adv5, 26.4719), 4.58418), 7.18088)) - rank(decay_linear(Ts_Rank(Ts_ArgMin(correlation(rank(open), rank(adv15), 20.8187), 8.62571), 6.95668), 8.07206)))", + "alpha 99": "((rank(correlation(sum(((high + low) / 2), 19.8975), sum(adv60, 19.8975), 8.8136)) < rank(correlation(low, volume, 6.28259))) * -1)", + "alpha 101": "((close - open) / ((high - low) + .001))", + "alpha 48": "(indneutralize(((correlation(delta(close, 1), delta(delay(close, 1), 1), 250) * delta(close, 1)) / close), IndClass.subindustry) / sum(((delta(close, 1) / delay(close, 1))^2), 250))", + "alpha 56": "(0 - (1 * (rank((sum(returns, 10) / sum(sum(returns, 2), 3))) * rank((returns * cap)))))", + "alpha 58": "(-1 * Ts_Rank(decay_linear(correlation(IndNeutralize(vwap, IndClass.sector), volume, 3.92795), 7.89291), 5.50322))", + "alpha 59": "(-1 * Ts_Rank(decay_linear(correlation(IndNeutralize(((vwap * 0.728317) + (vwap * (1 - 0.728317))), IndClass.industry), volume, 4.25197), 16.2289), 8.19648))", + "alpha 63": "((rank(decay_linear(delta(IndNeutralize(close, IndClass.industry), 2.25164), 8.22237)) - rank(decay_linear(correlation(((vwap * 0.318108) + (open * (1 - 0.318108))), sum(adv180, 37.2467), 13.557), 12.2883))) * -1)", + "alpha 67": "((rank((high - ts_min(high, 2.14593)))^rank(correlation(IndNeutralize(vwap, IndClass.sector), IndNeutralize(adv20, IndClass.subindustry), 6.02936))) * -1)", + "alpha 69": "((rank(ts_max(delta(IndNeutralize(vwap, IndClass.industry), 2.72412), 4.79344))^Ts_Rank(correlation(((close * 0.490655) + (vwap * (1 - 0.490655))), adv20, 4.92416), 9.0615)) * -1)", + "alpha 70": "((rank(delta(vwap, 1.29456))^Ts_Rank(correlation(IndNeutralize(close, IndClass.industry), adv50, 17.8256), 17.9171)) * -1)", + "alpha 76": "(max(rank(decay_linear(delta(vwap, 1.24383), 11.8259)), Ts_Rank(decay_linear(Ts_Rank(correlation(IndNeutralize(low, IndClass.sector), adv81, 8.14941), 19.569), 17.1543), 19.383)) * -1)", + "alpha 79": "(rank(delta(IndNeutralize(((close * 0.60733) + (open * (1 - 0.60733))), IndClass.sector), 1.23438)) < rank(correlation(Ts_Rank(vwap, 3.60973), Ts_Rank(adv150, 9.18637), 14.6644)))", + "alpha 80": "((rank(Sign(delta(IndNeutralize(((open * 0.868128) + (high * (1 - 0.868128))), IndClass.industry), 4.04545)))^Ts_Rank(correlation(high, adv10, 5.11456), 5.53756)) * -1)", + "alpha 82": "(min(rank(decay_linear(delta(open, 1.46063), 14.8717)), Ts_Rank(decay_linear(correlation(IndNeutralize(volume, IndClass.sector), ((open * 0.634196) + (open * (1 - 0.634196))), 17.4842), 6.92131), 13.4283)) * -1)", + "alpha 87": "(max(rank(decay_linear(delta(((close * 0.369701) + (vwap * (1 - 0.369701))), 1.91233), 2.65461)), Ts_Rank(decay_linear(abs(correlation(IndNeutralize(adv81, IndClass.industry), close, 13.4132)), 4.89768), 14.4535)) * -1)", + "alpha 89": "(Ts_Rank(decay_linear(correlation(((low * 0.967285) + (low * (1 - 0.967285))), adv10, 6.94279), 5.51607), 3.79744) - Ts_Rank(decay_linear(delta(IndNeutralize(vwap, IndClass.industry), 3.48158), 10.1466), 15.3012))", + "alpha 90": "((rank((close - ts_max(close, 4.66719)))^Ts_Rank(correlation(IndNeutralize(adv40, IndClass.subindustry), low, 5.38375), 3.21856)) * -1)", + "alpha 91": "((Ts_Rank(decay_linear(decay_linear(correlation(IndNeutralize(close, IndClass.industry), volume, 9.74928), 16.398), 3.83219), 4.8667) - rank(decay_linear(correlation(vwap, adv30, 4.01303), 2.6809))) * -1)", + "alpha 93": "(Ts_Rank(decay_linear(correlation(IndNeutralize(vwap, IndClass.industry), adv81, 17.4193), 19.848), 7.54455) / rank(decay_linear(delta(((close * 0.524434) + (vwap * (1 - 0.524434))), 2.77377), 16.2664)))", + "alpha 97": "((rank(decay_linear(delta(IndNeutralize(((low * 0.721001) + (vwap * (1 - 0.721001))), IndClass.industry), 3.3705), 20.4523)) - Ts_Rank(decay_linear(Ts_Rank(correlation(Ts_Rank(low, 7.87871), Ts_Rank(adv60, 17.255), 4.97547), 18.5925), 15.7152), 6.71659)) * -1)", + "alpha 100": "(0 - (1 * (((1.5 * scale(indneutralize(indneutralize(rank(((((close - low) - (high - close)) / (high - low)) * volume)), IndClass.subindustry), IndClass.subindustry))) - scale(indneutralize((correlation(close, rank(adv20), 5) - rank(ts_argmin(close, 30))), IndClass.subindustry))) * (volume / adv20))))" +} \ No newline at end of file diff --git a/wq101alphas/wq101alpha2json.py b/wq101alphas/wq101alpha2json.py new file mode 100644 index 0000000..fb37a6e --- /dev/null +++ b/wq101alphas/wq101alpha2json.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +import json + +lines = [] + +with open('wq101alpha.dos', 'r') as f: + for line in f: + if line.startswith('//'): + lines.append(line) + +data = {} + +for i, v in enumerate(lines): + if "//alpha" in v: + data[v.replace("//", "").replace("\n", "")] = lines[i+1].replace("//", "").replace("\n", "") + +# 将 data 写入当前路径中, json 文件, 命名为 wq101alpha.json +with open('wq101alpha.json', 'w') as f: + json.dump(data, f, ensure_ascii=False, indent=4) + print("wq101alpha.json 文件已生成") diff --git a/wqb-demo/alphas.json b/wqb-demo/alphas.json new file mode 100644 index 0000000..db4e59d --- /dev/null +++ b/wqb-demo/alphas.json @@ -0,0 +1,56 @@ +[ + { + "name": "做空股价潜力有限", + "expression": "-rank(ebit / capex)", + "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 + } + }, + { + "name": "财务健康度标准化", + "expression": "zscore(cash_st / debt_st)", + "settings": { + "instrumentType": "EQUITY", + "region": "USA", + "universe": "TOP3000", + "delay": 1, + "decay": 0, + "neutralization": "INDUSTRY", + "truncation": 0.1, + "pasteurization": "ON", + "unitHandling": "VERIFY", + "nanHandling": "OFF", + "language": "FASTEXPR", + "visualization": false + } + }, + { + "name": "做空12个月社交媒体讨论热度高", + "expression": "-scl12_buzz", + "settings": { + "instrumentType": "EQUITY", + "region": "USA", + "universe": "TOP3000", + "delay": 1, + "decay": 0, + "neutralization": "INDUSTRY", + "truncation": 0.12, + "pasteurization": "ON", + "unitHandling": "VERIFY", + "nanHandling": "OFF", + "language": "FASTEXPR", + "visualization": false + } + } +] \ No newline at end of file diff --git a/wqb-demo/brain_credentials.txt b/wqb-demo/brain_credentials.txt new file mode 100644 index 0000000..7716cbb --- /dev/null +++ b/wqb-demo/brain_credentials.txt @@ -0,0 +1 @@ +['uname', 'pw'] \ No newline at end of file diff --git a/wqb-demo/main.py b/wqb-demo/main.py new file mode 100644 index 0000000..55368e0 --- /dev/null +++ b/wqb-demo/main.py @@ -0,0 +1,247 @@ +import httpx +import json +from concurrent.futures import ThreadPoolExecutor, as_completed +from os.path import expanduser, exists +from httpx import BasicAuth +from time import sleep +from datetime import datetime + + +class WorldQuantBrainAPI: + def __init__(self, credentials_file='brain_credentials.txt'): + """初始化API客户端""" + self.credentials_file = expanduser(credentials_file) + self.client = None + self.brain_api_url = 'https://api.worldquantbrain.com' + + def login(self): + """登录认证""" + try: + # 检查凭证文件是否存在 + if not exists(self.credentials_file): + print(f"❌ 凭证文件不存在: {self.credentials_file}") + return False + + # Load credentials + with open(self.credentials_file) as f: + file_content = f.read().strip() + + with open(self.credentials_file) as f: + credentials = eval(f.read()) + + # Extract username and password from the list + if len(credentials) != 2: + print(f"❌ 凭证格式错误,应该是 [username, password] 格式,但得到: {credentials}") + return False + + username, password = credentials + + # Create a client with basic authentication + self.client = httpx.Client(auth=BasicAuth(username, password)) + + # Send authentication request + 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.text}") + return False + + except json.JSONDecodeError as e: + print(f"❌ JSON解析错误: {e}") + print(f"📄 文件内容: {file_content if 'file_content' in locals() else '无法读取'}") + return False + except Exception as e: + print(f"❌ 登录过程中出错: {str(e)}") + return False + + def batch_simulate_alphas(self, alphas_config_file='alphas.json', max_workers=3): + """批量测试多个Alpha因子(使用线程池)""" + # 检查配置文件是否存在 + if not exists(alphas_config_file): + print(f"❌ 配置文件 {alphas_config_file} 不存在") + return [] + + # 读取Alpha配置 + try: + with open(alphas_config_file, 'r', encoding='utf-8') as f: + file_content = f.read().strip() + print(f"📄 Alpha配置文件内容预览: {file_content[:200]}...") # 只显示前200个字符 + + with open(alphas_config_file, 'r', encoding='utf-8') as f: + alpha_configs = json.load(f) + + print(f"✅ 成功读取 {len(alpha_configs)} 个Alpha配置") + for i, config in enumerate(alpha_configs): + print(f" {i+1}. {config.get('name', '未命名')}") + + except json.JSONDecodeError as e: + print(f"❌ 配置文件 JSON格式错误: {e}") + print(f"📄 出错的文件内容: {file_content if 'file_content' in locals() else '无法读取'}") + return [] + except Exception as e: + print(f"❌ 读取配置文件时出错: {str(e)}") + return [] + + print(f"📁 读取到 {len(alpha_configs)} 个Alpha配置") + + # 登录 + if not self.login(): + print("❌ 登录失败,无法继续") + return [] + + results = [] + + # 使用线程池并发执行 + with ThreadPoolExecutor(max_workers=max_workers) as executor: + # 提交所有任务 + future_to_alpha = { + executor.submit(self.simulate_alpha, config): config + for config in alpha_configs + } + + # 收集结果 + for future in as_completed(future_to_alpha): + config = future_to_alpha[future] + try: + result = future.result() + results.append(result) + except Exception as e: + print(f"❌ {config.get('name', '未知Alpha')} 执行失败: {str(e)}") + results.append({ + 'name': config.get('name', '未知Alpha'), + 'success': False, + 'error': str(e) + }) + + # 打印汇总结果 + self._print_summary(results) + return results + + def simulate_alpha(self, alpha_config): + """模拟单个Alpha因子""" + if self.client is None: + raise Exception("请先调用 login() 方法登录") + + name = alpha_config.get('name', '未命名Alpha') + expression = alpha_config['expression'] + settings = alpha_config.get('settings', {}) + + print(f"\n🚀 开始模拟: {name}") + print(f"📝 表达式: {expression}") + + simulation_data = { + 'type': 'REGULAR', + 'settings': settings, + 'regular': expression + } + + try: + # 发送模拟数据 + sim_resp = self.client.post( + f'{self.brain_api_url}/simulations', + json=simulation_data, + ) + print(f"📤 模拟提交状态: {sim_resp.status_code}") + + if sim_resp.status_code != 201: + print(f"❌ {name} 提交失败: {sim_resp.text}") + return {'name': name, 'success': False, 'error': f'提交失败: {sim_resp.status_code}'} + + # 获取进度URL并轮询结果 + sim_progress_url = sim_resp.headers['location'] + print(f"⏳ {name} 进度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: # simulation done! + break + print(f"⏰ {name} 等待 {retry_after_sec} 秒...") + sleep(retry_after_sec) + + # 获取最终的alpha ID + result_data = sim_progress_resp.json() + alpha_id = result_data["alpha"] + print(f"✅ {name} 模拟完成! Alpha ID: {alpha_id}") + + return { + 'name': name, + 'expression': expression, + 'alpha_id': alpha_id, + 'success': True, + 'result_data': result_data + } + + except Exception as e: + print(f"❌ {name} 模拟过程中出错: {str(e)}") + return {'name': name, 'success': False, 'error': str(e)} + + def _print_summary(self, results): + """打印测试结果汇总""" + print("\n" + "=" * 50) + print("📊 Alpha测试结果汇总") + print("=" * 50) + + success_count = sum(1 for r in results if r.get('success', False)) + failed_count = len(results) - success_count + + print(f"✅ 成功: {success_count} 个") + print(f"❌ 失败: {failed_count} 个") + + print("\n成功详情:") + for result in results: + if result.get('success'): + print(f" ✓ {result['name']}: {result['alpha_id']}") + + if failed_count > 0: + print("\n失败详情:") + for result in results: + if not result.get('success'): + print(f" ✗ {result['name']}: {result.get('error', '未知错误')}") + + def close(self): + """关闭客户端连接""" + if self.client: + self.client.close() + self.client = None + + +# 使用示例 +if __name__ == "__main__": + # 创建API实例 + wq_api = WorldQuantBrainAPI() + + try: + # 1. 批量测试所有Alpha + print("🎯 开始批量测试Alpha因子...") + start_time = datetime.now() + + results = wq_api.batch_simulate_alphas( + alphas_config_file='alphas.json', + max_workers=2 # 并发数量,根据API限制调整 + ) + + end_time = datetime.now() + print(f"\n⏱️ 测试总耗时: {(end_time - start_time).total_seconds():.2f} 秒") + + # 2. 提取成功的Alpha ID + successful_alphas = [r for r in results if r.get('success')] + alpha_ids = [r['alpha_id'] for r in successful_alphas] + + print(f"\n📋 成功模拟的Alpha数量: {len(alpha_ids)}") + for alpha in successful_alphas: + print(f" - {alpha['name']}: {alpha['alpha_id']}") + + except Exception as e: + print(f"❌ 程序执行出错: {str(e)}") + import traceback + traceback.print_exc() # 打印完整的错误堆栈 + + finally: + # 确保连接关闭 + wq_api.close() \ No newline at end of file diff --git a/wqb-demo/main_simple.py b/wqb-demo/main_simple.py new file mode 100644 index 0000000..0472bb9 --- /dev/null +++ b/wqb-demo/main_simple.py @@ -0,0 +1,100 @@ +import httpx +import json +from httpx import BasicAuth +from time import sleep + +class WorldQuantBrainAPI: + def __init__(self, credentials_file='brain_credentials.txt'): + self.credentials_file = credentials_file + self.client = None + self.brain_api_url = 'https://api.worldquantbrain.com' + + def load_credentials(self): + """读取本地账号密码""" + 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 + + def simulate_alpha(self, expression, settings=None): + """模拟Alpha因子""" + 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} 秒...") + sleep(retry_after_sec) + + alpha_id = sim_progress_resp.json()["alpha"] + print(f"生成的Alpha ID: {alpha_id}") + return alpha_id + + def close(self): + """关闭连接""" + if self.client: + self.client.close() + +if __name__ == "__main__": + api = WorldQuantBrainAPI() + + try: + # 读取账号密码并登录 + if api.login(): + # 模拟Alpha因子 + alpha_id = api.simulate_alpha("liabilities/assets") + print(f"模拟完成,Alpha ID: {alpha_id}") + finally: + api.close() \ No newline at end of file diff --git a/wqb-demo/requirements.txt b/wqb-demo/requirements.txt new file mode 100644 index 0000000..aebd9d2 --- /dev/null +++ b/wqb-demo/requirements.txt @@ -0,0 +1 @@ +httpx==0.28.1 \ No newline at end of file diff --git a/wqb-demo/simulation_results.json b/wqb-demo/simulation_results.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/wqb-demo/simulation_results.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/wqb-test/main.py b/wqb-test/main.py new file mode 100644 index 0000000..fd96f58 --- /dev/null +++ b/wqb-test/main.py @@ -0,0 +1,73 @@ +import requests +from time import sleep + +def quick_test_alpha(username, password, alpha_expression, region="USA"): + """ + 快速测试alpha表达式 + + Parameters: + - username: 用户名 + - password: 密码 + - alpha_expression: 因子表达式 + - region: 区域 (USA, EUROPE, ASIA, CHINA等) + """ + + # 登录 + s = requests.Session() + s.auth = (username, password) + s.post('https://api.worldquantbrain.com/authentication') + + # 设置 + settings = { + 'instrumentType': 'EQUITY', + 'region': region, + 'universe': 'TOP3000', + 'delay': 1, + 'decay': 8, + 'neutralization': 'SUBINDUSTRY', + 'truncation': 0.08, + 'pasteurization': 'ON', + 'testPeriod': 'P2Y', + 'language': 'FASTEXPR', + } + + # 提交测试 + simulation_data = { + 'type': 'REGULAR', + 'settings': settings, + 'regular': alpha_expression + } + + response = s.post('https://api.worldquantbrain.com/simulations', json=simulation_data) + progress_url = response.headers['Location'] + + # 等待结果 + while True: + progress = s.get(progress_url) + if progress.headers.get("Retry-After", 0) == 0: + break + sleep(float(progress.headers["Retry-After"])) + + result = progress.json() + + if result["status"] == "COMPLETE": + alpha_info = result["is"] + return { + "alpha_id": result["alpha"], + "sharpe": alpha_info["sharpe"], + "fitness": alpha_info["fitness"], + "turnover": alpha_info["turnover"], + "margin": alpha_info["margin"] + } + else: + return {"error": "模拟失败", "status": result["status"]} + +# 使用示例 +if __name__ == "__main__": + result = quick_test_alpha( + "jack0210_@hotmail.com", + "!QAZ2wsx+0913", + "rank(ts_delta(close, 5))", # 你的alpha表达式 + "USA" + ) + print(result) \ No newline at end of file