mlquantx 0.2.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mlquant/__init__.py +18 -0
- mlquant/backtest/__init__.py +14 -0
- mlquant/backtest/engine.py +118 -0
- mlquant/backtest/metrics.py +95 -0
- mlquant/cli/__init__.py +1 -0
- mlquant/cli/main.py +292 -0
- mlquant/configs/__init__.py +1 -0
- mlquant/configs/small.yaml +41 -0
- mlquant/data/__init__.py +88 -0
- mlquant/data/akshare_loader.py +168 -0
- mlquant/data/baostock_loader.py +137 -0
- mlquant/data/loaders.py +125 -0
- mlquant/data/panel.py +206 -0
- mlquant/data/synthetic.py +138 -0
- mlquant/data/yfinance_loader.py +101 -0
- mlquant/features/__init__.py +42 -0
- mlquant/features/_factors_add.py +288 -0
- mlquant/features/_factors_alpha101.py +98 -0
- mlquant/features/_factors_best.py +177 -0
- mlquant/features/_factors_better.py +385 -0
- mlquant/features/_factors_change.py +53 -0
- mlquant/features/_factors_extra.py +147 -0
- mlquant/features/_factors_market.py +61 -0
- mlquant/features/_factors_old.py +563 -0
- mlquant/features/_factors_original.py +215 -0
- mlquant/features/_factors_stock.py +270 -0
- mlquant/features/alpha101.py +84 -0
- mlquant/features/bias.py +81 -0
- mlquant/features/legacy_factors.py +126 -0
- mlquant/features/market_breadth.py +190 -0
- mlquant/features/neutralize.py +75 -0
- mlquant/features/target.py +62 -0
- mlquant/features/tensor_factors.py +301 -0
- mlquant/features.py +613 -0
- mlquant/models/__init__.py +8 -0
- mlquant/models/losses.py +88 -0
- mlquant/models/nets.py +62 -0
- mlquant/portfolio/__init__.py +5 -0
- mlquant/portfolio/frontier.py +49 -0
- mlquant/portfolio/markowitz.py +144 -0
- mlquant/training/__init__.py +6 -0
- mlquant/training/augment.py +89 -0
- mlquant/training/dataset.py +50 -0
- mlquant/training/trainer.py +108 -0
- mlquant/utils/__init__.py +5 -0
- mlquant/utils/config.py +60 -0
- mlquant/utils/seed.py +35 -0
- mlquantx-0.2.5.dist-info/METADATA +108 -0
- mlquantx-0.2.5.dist-info/RECORD +54 -0
- mlquantx-0.2.5.dist-info/WHEEL +5 -0
- mlquantx-0.2.5.dist-info/entry_points.txt +2 -0
- mlquantx-0.2.5.dist-info/licenses/LICENSE +21 -0
- mlquantx-0.2.5.dist-info/licenses/NOTICE.md +5 -0
- mlquantx-0.2.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
"""old_* family: legacy alpha signals (50 factors, old_027 through old_076).
|
|
2
|
+
|
|
3
|
+
Ported from legacy Feature.py old_027-old_076.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from typing import Tuple
|
|
7
|
+
import torch
|
|
8
|
+
|
|
9
|
+
from ..data.panel import Panel
|
|
10
|
+
from .tensor_factors import (
|
|
11
|
+
cs_rank, delay, delta, ewma, ts_corr, ts_max, ts_mean, ts_min, ts_rank, ts_std, ts_sum,
|
|
12
|
+
)
|
|
13
|
+
from .legacy_factors import register_legacy_factor, _close_loc, _amount
|
|
14
|
+
|
|
15
|
+
Tensor = torch.Tensor
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@register_legacy_factor("old_027")
|
|
19
|
+
def old_027(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
20
|
+
"""rank(volume) * rank(vwap - close)."""
|
|
21
|
+
vr, vm = cs_rank(panel.volume, panel.mask)
|
|
22
|
+
diff = panel.vwap - panel.close
|
|
23
|
+
dr, dm = cs_rank(diff, panel.mask)
|
|
24
|
+
m = vm & dm
|
|
25
|
+
return (vr * dr) * m.float(), m
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@register_legacy_factor("old_028")
|
|
29
|
+
def old_028(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
30
|
+
"""corr(rank(open), rank(volume), 10)."""
|
|
31
|
+
ro, om = cs_rank(panel.open, panel.mask)
|
|
32
|
+
rv, vm = cs_rank(panel.volume, panel.mask)
|
|
33
|
+
m = om & vm
|
|
34
|
+
return ts_corr(ro, rv, m, 10)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@register_legacy_factor("old_029")
|
|
38
|
+
def old_029(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
39
|
+
"""ts_min(rank(corr(close, volume, 5)), 12)."""
|
|
40
|
+
c, cm = ts_corr(panel.close, panel.volume, panel.mask, 5)
|
|
41
|
+
r, rm = cs_rank(c * cm.float(), cm)
|
|
42
|
+
return ts_min(r, rm, 12)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@register_legacy_factor("old_030")
|
|
46
|
+
def old_030(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
47
|
+
"""sign(Δclose, 5) * (1 - rank(Δvolume, 5))."""
|
|
48
|
+
dc, dm = delta(panel.close, panel.mask, 5)
|
|
49
|
+
dv, dvm = delta(panel.volume, panel.mask, 5)
|
|
50
|
+
m = dm & dvm
|
|
51
|
+
dvr, _ = cs_rank(dv, m)
|
|
52
|
+
out = torch.sign(dc) * (1.0 - dvr)
|
|
53
|
+
return out * m.float(), m
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@register_legacy_factor("old_031")
|
|
57
|
+
def old_031(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
58
|
+
"""rank(Δclose, 10) * rank(Δvolume/vol, 10)."""
|
|
59
|
+
dc, dm = delta(panel.close, panel.mask, 10)
|
|
60
|
+
dv, dvm = delta(panel.volume, panel.mask, 10)
|
|
61
|
+
m = dm & dvm
|
|
62
|
+
vol_r = dv / panel.volume.clamp_min(1.0)
|
|
63
|
+
r1, _ = cs_rank(dc, m)
|
|
64
|
+
r2, _ = cs_rank(vol_r, m)
|
|
65
|
+
return (r1 * r2) * m.float(), m
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@register_legacy_factor("old_032")
|
|
69
|
+
def old_032(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
70
|
+
"""ts_mean(close, 7) - close + corr(vwap, delay(close,5), 230)."""
|
|
71
|
+
avg, am = ts_mean(panel.close, panel.mask, 7)
|
|
72
|
+
dev = avg - panel.close
|
|
73
|
+
prev, pm = delay(panel.close, panel.mask, 5)
|
|
74
|
+
# Use shorter window (20) as proxy for 230 (data may be short)
|
|
75
|
+
c, cm = ts_corr(panel.vwap, prev, pm, 20)
|
|
76
|
+
m = am & cm
|
|
77
|
+
return (dev + c) * m.float(), m
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@register_legacy_factor("old_033")
|
|
81
|
+
def old_033(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
82
|
+
"""rank(-1 + open/close)."""
|
|
83
|
+
out = -1.0 + panel.open / panel.close.clamp_min(1e-9)
|
|
84
|
+
return cs_rank(out, panel.mask)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@register_legacy_factor("old_034")
|
|
88
|
+
def old_034(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
89
|
+
"""rank(1 - rank(std(ret, 2)/std(ret, 5)) + 1 - rank(Δclose, 1))."""
|
|
90
|
+
ret, rm = delta(panel.close, panel.mask, 1)
|
|
91
|
+
ret = ret / panel.close.clamp_min(1e-9)
|
|
92
|
+
s2, sm2 = ts_std(ret, rm, 2)
|
|
93
|
+
s5, sm5 = ts_std(ret, rm, 5)
|
|
94
|
+
m = sm2 & sm5
|
|
95
|
+
ratio = s2 / s5.clamp_min(1e-9)
|
|
96
|
+
rr, _ = cs_rank(ratio, m)
|
|
97
|
+
dc, dcm = delta(panel.close, panel.mask, 1)
|
|
98
|
+
dcr, _ = cs_rank(dc, dcm)
|
|
99
|
+
m2 = m & dcm
|
|
100
|
+
out = 2.0 - rr - dcr
|
|
101
|
+
return cs_rank(out * m2.float(), m2)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@register_legacy_factor("old_035")
|
|
105
|
+
def old_035(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
106
|
+
"""ts_rank(volume, 32) * (1 - ts_rank(close + high - low, 16))."""
|
|
107
|
+
vr, vm = ts_rank(panel.volume, panel.mask, 32)
|
|
108
|
+
x = panel.close + panel.high - panel.low
|
|
109
|
+
xr, xm = ts_rank(x, panel.mask, 16)
|
|
110
|
+
m = vm & xm
|
|
111
|
+
out = vr * (1.0 - xr)
|
|
112
|
+
return out * m.float(), m
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@register_legacy_factor("old_036")
|
|
116
|
+
def old_036(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
117
|
+
"""rank(corr(delay(open-close,1), close, 20)) + rank(open-close)."""
|
|
118
|
+
oc = panel.open - panel.close
|
|
119
|
+
oc_d, dm = delay(oc, panel.mask, 1)
|
|
120
|
+
c, cm = ts_corr(oc_d, panel.close, dm, 20)
|
|
121
|
+
rc, rcm = cs_rank(c * cm.float(), cm)
|
|
122
|
+
roc, rocm = cs_rank(oc, panel.mask)
|
|
123
|
+
m = rcm & rocm
|
|
124
|
+
return (rc + roc) * m.float(), m
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@register_legacy_factor("old_037")
|
|
128
|
+
def old_037(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
129
|
+
"""-rank(open - delay(high, 1)) * rank(open - delay(close, 1)) * rank(open - delay(low, 1))."""
|
|
130
|
+
dh, m1 = delay(panel.high, panel.mask, 1)
|
|
131
|
+
dc, m2 = delay(panel.close, panel.mask, 1)
|
|
132
|
+
dl, m3 = delay(panel.low, panel.mask, 1)
|
|
133
|
+
m = m1 & m2 & m3
|
|
134
|
+
r1, _ = cs_rank(panel.open - dh, m)
|
|
135
|
+
r2, _ = cs_rank(panel.open - dc, m)
|
|
136
|
+
r3, _ = cs_rank(panel.open - dl, m)
|
|
137
|
+
out = -(r1 * r2 * r3)
|
|
138
|
+
return out * m.float(), m
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@register_legacy_factor("old_038")
|
|
142
|
+
def old_038(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
143
|
+
"""-(rank(open) ^ rank(close/vwap))."""
|
|
144
|
+
ro, om = cs_rank(panel.open, panel.mask)
|
|
145
|
+
ratio = panel.close / panel.vwap.clamp_min(1e-9)
|
|
146
|
+
rr, rm = cs_rank(ratio, panel.mask)
|
|
147
|
+
m = om & rm
|
|
148
|
+
out = -(ro.abs().clamp_min(1e-12).pow(rr.clamp(0.01, 2)))
|
|
149
|
+
return out * m.float(), m
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@register_legacy_factor("old_039")
|
|
153
|
+
def old_039(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
154
|
+
"""-rank(Δclose, 7) * (1 - rank(ewma(volume*ret/close, 1/20)))."""
|
|
155
|
+
dc, dm = delta(panel.close, panel.mask, 7)
|
|
156
|
+
ret, rm = delta(panel.close, panel.mask, 1)
|
|
157
|
+
ret = ret / panel.close.clamp_min(1e-9)
|
|
158
|
+
signal = panel.volume * ret
|
|
159
|
+
ew, em = ewma(signal, rm, alpha=1.0 / 20.0)
|
|
160
|
+
ewr, ewrm = cs_rank(ew, em)
|
|
161
|
+
dcr, dcrm = cs_rank(dc, dm)
|
|
162
|
+
m = dcrm & ewrm
|
|
163
|
+
out = -dcr * (1.0 - ewr)
|
|
164
|
+
return out * m.float(), m
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@register_legacy_factor("old_040")
|
|
168
|
+
def old_040(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
169
|
+
"""-rank(std(high, 10)) * corr(high, volume, 10)."""
|
|
170
|
+
sd, sm = ts_std(panel.high, panel.mask, 10)
|
|
171
|
+
sdr, sdrm = cs_rank(sd, sm)
|
|
172
|
+
c, cm = ts_corr(panel.high, panel.volume, panel.mask, 10)
|
|
173
|
+
m = sdrm & cm
|
|
174
|
+
out = -sdr * c
|
|
175
|
+
return out * m.float(), m
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@register_legacy_factor("old_041")
|
|
179
|
+
def old_041(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
180
|
+
"""(high * low)^0.5 - vwap."""
|
|
181
|
+
out = (panel.high * panel.low).clamp_min(0).sqrt() - panel.vwap
|
|
182
|
+
return out * panel.mask.float(), panel.mask
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@register_legacy_factor("old_042")
|
|
186
|
+
def old_042(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
187
|
+
"""rank(vwap - close) / rank(vwap + close)."""
|
|
188
|
+
r1, m1 = cs_rank(panel.vwap - panel.close, panel.mask)
|
|
189
|
+
r2, m2 = cs_rank(panel.vwap + panel.close, panel.mask)
|
|
190
|
+
m = m1 & m2
|
|
191
|
+
out = r1 / r2.abs().clamp_min(1e-9)
|
|
192
|
+
return out * m.float(), m
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@register_legacy_factor("old_043")
|
|
196
|
+
def old_043(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
197
|
+
"""ts_rank(volume / mean(volume, 20), 20) * ts_rank(-Δclose, 7)."""
|
|
198
|
+
avg, am = ts_mean(panel.volume, panel.mask, 20)
|
|
199
|
+
ratio = panel.volume / avg.clamp_min(1.0)
|
|
200
|
+
vr, vm = ts_rank(ratio, am, 20)
|
|
201
|
+
dc, dm = delta(panel.close, panel.mask, 7)
|
|
202
|
+
dcr, dcm = ts_rank(-dc, dm, 20)
|
|
203
|
+
m = vm & dcm
|
|
204
|
+
return (vr * dcr) * m.float(), m
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@register_legacy_factor("old_044")
|
|
208
|
+
def old_044(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
209
|
+
"""-corr(high, rank(volume), 5)."""
|
|
210
|
+
rv, vm = cs_rank(panel.volume, panel.mask)
|
|
211
|
+
c, cm = ts_corr(panel.high, rv, vm, 5)
|
|
212
|
+
return (-c) * cm.float(), cm
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
@register_legacy_factor("old_045")
|
|
216
|
+
def old_045(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
217
|
+
"""-rank(sum(delay(close,5), 20)/20) * corr(close, volume, 2)."""
|
|
218
|
+
prev, pm = delay(panel.close, panel.mask, 5)
|
|
219
|
+
s, sm = ts_mean(prev, pm, 20)
|
|
220
|
+
sr, srm = cs_rank(s, sm)
|
|
221
|
+
c, cm = ts_corr(panel.close, panel.volume, panel.mask, 2)
|
|
222
|
+
m = srm & cm
|
|
223
|
+
return (-sr * c) * m.float(), m
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@register_legacy_factor("old_046")
|
|
227
|
+
def old_046(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
228
|
+
"""(mean(close,3)+mean(close,6)+mean(close,12)+mean(close,24))/(4*close) - 1."""
|
|
229
|
+
m3, mm3 = ts_mean(panel.close, panel.mask, 3)
|
|
230
|
+
m6, mm6 = ts_mean(panel.close, panel.mask, 6)
|
|
231
|
+
m12, mm12 = ts_mean(panel.close, panel.mask, 12)
|
|
232
|
+
m24, mm24 = ts_mean(panel.close, panel.mask, 24)
|
|
233
|
+
m = mm3 & mm6 & mm12 & mm24
|
|
234
|
+
out = (m3 + m6 + m12 + m24) / (4.0 * panel.close.clamp_min(1e-9)) - 1.0
|
|
235
|
+
return out * m.float(), m
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@register_legacy_factor("old_047")
|
|
239
|
+
def old_047(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
240
|
+
"""(ts_max(high, 6) - close) / (ts_max(high, 6) - ts_min(low, 6) + eps) * 100."""
|
|
241
|
+
mx, mxm = ts_max(panel.high, panel.mask, 6)
|
|
242
|
+
mn, mnm = ts_min(panel.low, panel.mask, 6)
|
|
243
|
+
m = mxm & mnm
|
|
244
|
+
rng = (mx - mn).clamp_min(1e-9)
|
|
245
|
+
out = (mx - panel.close) / rng * 100.0
|
|
246
|
+
return out * m.float(), m
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@register_legacy_factor("old_048")
|
|
250
|
+
def old_048(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
251
|
+
"""(-Δclose, 1) * volume / ewma(volume, 1/20)."""
|
|
252
|
+
dc, dm = delta(panel.close, panel.mask, 1)
|
|
253
|
+
ew, em = ewma(panel.volume, panel.mask, alpha=1.0 / 20.0)
|
|
254
|
+
m = dm & em
|
|
255
|
+
out = -dc * panel.volume / ew.clamp_min(1.0)
|
|
256
|
+
return out * m.float(), m
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@register_legacy_factor("old_049")
|
|
260
|
+
def old_049(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
261
|
+
"""Conditional: if close<delay(close,1): Δclose else 0 over 20 days sum."""
|
|
262
|
+
prev, pm = delay(panel.close, panel.mask, 1)
|
|
263
|
+
dc = panel.close - prev
|
|
264
|
+
down = (dc * (dc < 0).float()) * pm.float()
|
|
265
|
+
return ts_sum(down, pm, 20)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@register_legacy_factor("old_050")
|
|
269
|
+
def old_050(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
270
|
+
"""-ts_max(rank(corr(rank(volume), rank(vwap), 5)), 5)."""
|
|
271
|
+
rv, vm = cs_rank(panel.volume, panel.mask)
|
|
272
|
+
rvw, vwm = cs_rank(panel.vwap, panel.mask)
|
|
273
|
+
m = vm & vwm
|
|
274
|
+
c, cm = ts_corr(rv, rvw, m, 5)
|
|
275
|
+
cr, crm = cs_rank(c * cm.float(), cm)
|
|
276
|
+
mx, mxm = ts_max(cr, crm, 5)
|
|
277
|
+
return (-mx) * mxm.float(), mxm
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@register_legacy_factor("old_051")
|
|
281
|
+
def old_051(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
282
|
+
"""If close<delay(close,1): Δclose else 0 - conditional neg momentum sum 12."""
|
|
283
|
+
prev, pm = delay(panel.close, panel.mask, 1)
|
|
284
|
+
dc = panel.close - prev
|
|
285
|
+
neg = (dc * (dc < 0).float()) * pm.float()
|
|
286
|
+
return ts_sum(neg, pm, 12)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
@register_legacy_factor("old_052")
|
|
290
|
+
def old_052(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
291
|
+
"""(sum(max(0, high-delay(close,1)), 26) / sum(max(0, delay(close,1)-low), 26) - 1) * 100."""
|
|
292
|
+
prev, pm = delay(panel.close, panel.mask, 1)
|
|
293
|
+
up = torch.clamp(panel.high - prev, min=0)
|
|
294
|
+
dn = torch.clamp(prev - panel.low, min=0)
|
|
295
|
+
su, um = ts_sum(up, pm, 26)
|
|
296
|
+
sd, dm2 = ts_sum(dn, pm, 26)
|
|
297
|
+
m = um & dm2
|
|
298
|
+
out = (su / sd.clamp_min(1e-9) - 1.0) * 100.0
|
|
299
|
+
return out * m.float(), m
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
@register_legacy_factor("old_053")
|
|
303
|
+
def old_053(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
304
|
+
"""ts_sum(close > delay(close, 1), 12) / 12 * 100."""
|
|
305
|
+
prev, pm = delay(panel.close, panel.mask, 1)
|
|
306
|
+
up = (panel.close > prev).float() * pm.float()
|
|
307
|
+
s, sm = ts_sum(up, pm, 12)
|
|
308
|
+
return (s / 12.0 * 100.0) * sm.float(), sm
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
@register_legacy_factor("old_054")
|
|
312
|
+
def old_054(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
313
|
+
"""(-1 * rank(std(|close-open|,10) + |close-open|) + rank(corr(close,open,10)))."""
|
|
314
|
+
co = (panel.close - panel.open).abs()
|
|
315
|
+
sd, sm = ts_std(co, panel.mask, 10)
|
|
316
|
+
x = sd + co
|
|
317
|
+
xr, xm = cs_rank(x, sm)
|
|
318
|
+
c, cm = ts_corr(panel.close, panel.open, panel.mask, 10)
|
|
319
|
+
cr, crm = cs_rank(c * cm.float(), cm)
|
|
320
|
+
m = xm & crm
|
|
321
|
+
out = -xr + cr
|
|
322
|
+
return out * m.float(), m
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
@register_legacy_factor("old_055")
|
|
326
|
+
def old_055(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
327
|
+
"""corr(rank(close-ts_min(low,12))/(ts_max(high,12)-ts_min(low,12)), rank(volume), 6)."""
|
|
328
|
+
mn, mnm = ts_min(panel.low, panel.mask, 12)
|
|
329
|
+
mx, mxm = ts_max(panel.high, panel.mask, 12)
|
|
330
|
+
m1 = mnm & mxm
|
|
331
|
+
rng = (mx - mn).clamp_min(1e-9)
|
|
332
|
+
pos = (panel.close - mn) / rng
|
|
333
|
+
rp, rpm = cs_rank(pos * m1.float(), m1)
|
|
334
|
+
rv, rvm = cs_rank(panel.volume, panel.mask)
|
|
335
|
+
m = rpm & rvm
|
|
336
|
+
return ts_corr(rp, rv, m, 6)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
@register_legacy_factor("old_056")
|
|
340
|
+
def old_056(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
341
|
+
"""-rank(sum(ret, 10)) * rank(corr(close, volume, 5)) * rank(returns volatility 20)."""
|
|
342
|
+
ret, rm = delta(panel.close, panel.mask, 1)
|
|
343
|
+
ret = ret / panel.close.clamp_min(1e-9)
|
|
344
|
+
s, sm = ts_sum(ret, rm, 10)
|
|
345
|
+
sr, srm = cs_rank(s, sm)
|
|
346
|
+
c, cm = ts_corr(panel.close, panel.volume, panel.mask, 5)
|
|
347
|
+
cr, crm = cs_rank(c * cm.float(), cm)
|
|
348
|
+
sd, sdm = ts_std(ret, rm, 20)
|
|
349
|
+
sdr, sdrm = cs_rank(sd, sdm)
|
|
350
|
+
m = srm & crm & sdrm
|
|
351
|
+
out = -(sr * cr * sdr)
|
|
352
|
+
return out * m.float(), m
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
@register_legacy_factor("old_057")
|
|
356
|
+
def old_057(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
357
|
+
"""close / ewma(close, 1/30) - 1."""
|
|
358
|
+
ew, em = ewma(panel.close, panel.mask, alpha=1.0 / 30.0)
|
|
359
|
+
out = panel.close / ew.clamp_min(1e-9) - 1.0
|
|
360
|
+
return out * em.float(), em
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
@register_legacy_factor("old_058")
|
|
364
|
+
def old_058(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
365
|
+
"""-volume * (close - delay(close,1))."""
|
|
366
|
+
prev, pm = delay(panel.close, panel.mask, 1)
|
|
367
|
+
out = -panel.volume * (panel.close - prev)
|
|
368
|
+
return out * pm.float(), pm
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
@register_legacy_factor("old_059")
|
|
372
|
+
def old_059(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
373
|
+
"""mean(volume * |ret|, 20) ranked."""
|
|
374
|
+
ret, rm = delta(panel.close, panel.mask, 1)
|
|
375
|
+
ret = (ret / panel.close.clamp_min(1e-9)).abs()
|
|
376
|
+
signal = panel.volume * ret
|
|
377
|
+
avg, am = ts_mean(signal, rm, 20)
|
|
378
|
+
return cs_rank(avg * am.float(), am)
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
@register_legacy_factor("old_060")
|
|
382
|
+
def old_060(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
383
|
+
"""2 * (rank(open - min(open, 12)) - rank((sum(ret, 60)/60 + 1)^2))."""
|
|
384
|
+
mn, mnm = ts_min(panel.open, panel.mask, 12)
|
|
385
|
+
r1, r1m = cs_rank((panel.open - mn) * mnm.float(), mnm)
|
|
386
|
+
ret, rm = delta(panel.close, panel.mask, 1)
|
|
387
|
+
ret = ret / panel.close.clamp_min(1e-9)
|
|
388
|
+
avg, am = ts_mean(ret, rm, 60)
|
|
389
|
+
sq = (avg + 1.0).pow(2)
|
|
390
|
+
r2, r2m = cs_rank(sq * am.float(), am)
|
|
391
|
+
m = r1m & r2m
|
|
392
|
+
out = 2.0 * (r1 - r2)
|
|
393
|
+
return out * m.float(), m
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
@register_legacy_factor("old_061")
|
|
397
|
+
def old_061(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
398
|
+
"""rank(vwap - ts_min(vwap, 16))."""
|
|
399
|
+
mn, mm = ts_min(panel.vwap, panel.mask, 16)
|
|
400
|
+
diff = (panel.vwap - mn) * mm.float()
|
|
401
|
+
return cs_rank(diff, mm)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
@register_legacy_factor("old_062")
|
|
405
|
+
def old_062(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
406
|
+
"""rank(corr(vwap, sum(mean(volume,20), 23), 5))."""
|
|
407
|
+
avg, am = ts_mean(panel.volume, panel.mask, 20)
|
|
408
|
+
s, sm = ts_sum(avg, am, 23)
|
|
409
|
+
c, cm = ts_corr(panel.vwap, s, sm, 5)
|
|
410
|
+
return cs_rank(c * cm.float(), cm)
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
@register_legacy_factor("old_063")
|
|
414
|
+
def old_063(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
415
|
+
"""max(rank(corr(rank(vwap), rank(volume), 4)), 8)."""
|
|
416
|
+
rv, vm = cs_rank(panel.vwap, panel.mask)
|
|
417
|
+
rvol, volm = cs_rank(panel.volume, panel.mask)
|
|
418
|
+
m = vm & volm
|
|
419
|
+
c, cm = ts_corr(rv, rvol, m, 4)
|
|
420
|
+
cr, crm = cs_rank(c * cm.float(), cm)
|
|
421
|
+
return ts_max(cr, crm, 8)
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
@register_legacy_factor("old_064")
|
|
425
|
+
def old_064(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
426
|
+
"""rank(corr(sum(open*0.178 + low*0.822, 15), sum(mean(volume,60), 9), 11))."""
|
|
427
|
+
x = panel.open * 0.178 + panel.low * 0.822
|
|
428
|
+
sx, sxm = ts_sum(x, panel.mask, 15)
|
|
429
|
+
avg, am = ts_mean(panel.volume, panel.mask, 60)
|
|
430
|
+
sa, sam = ts_sum(avg, am, 9)
|
|
431
|
+
m = sxm & sam
|
|
432
|
+
c, cm = ts_corr(sx, sa, m, 11)
|
|
433
|
+
return cs_rank(c * cm.float(), cm)
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
@register_legacy_factor("old_065")
|
|
437
|
+
def old_065(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
438
|
+
"""rank(corr(((open*0.147) + (vwap*0.853)), sum(mean(vol,6), 2), 6))."""
|
|
439
|
+
x = panel.open * 0.147 + panel.vwap * 0.853
|
|
440
|
+
avg, am = ts_mean(panel.volume, panel.mask, 6)
|
|
441
|
+
s, sm = ts_sum(avg, am, 2)
|
|
442
|
+
m = panel.mask & sm
|
|
443
|
+
c, cm = ts_corr(x, s, m, 6)
|
|
444
|
+
return cs_rank(c * cm.float(), cm)
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
@register_legacy_factor("old_066")
|
|
448
|
+
def old_066(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
449
|
+
"""rank(delta(vwap, 4))."""
|
|
450
|
+
d, dm = delta(panel.vwap, panel.mask, 4)
|
|
451
|
+
return cs_rank(d * dm.float(), dm)
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
@register_legacy_factor("old_067")
|
|
455
|
+
def old_067(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
456
|
+
"""(high - ts_max(high, 6)) / (ts_max(high, 6) + eps) * rank(corr(vwap, mean(vol,20), 4))."""
|
|
457
|
+
mx, mm = ts_max(panel.high, panel.mask, 6)
|
|
458
|
+
dist = (panel.high - mx) / mx.clamp_min(1e-9)
|
|
459
|
+
avg, am = ts_mean(panel.volume, panel.mask, 20)
|
|
460
|
+
c, cm = ts_corr(panel.vwap, avg, am, 4)
|
|
461
|
+
cr, crm = cs_rank(c * cm.float(), cm)
|
|
462
|
+
m = mm & crm
|
|
463
|
+
out = dist * cr
|
|
464
|
+
return out * m.float(), m
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
@register_legacy_factor("old_068")
|
|
468
|
+
def old_068(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
469
|
+
"""(rank(corr(high, mean(volume,15), 9)) * rank(corr(close, volume, 4)))."""
|
|
470
|
+
avg, am = ts_mean(panel.volume, panel.mask, 15)
|
|
471
|
+
c1, cm1 = ts_corr(panel.high, avg, am, 9)
|
|
472
|
+
r1, rm1 = cs_rank(c1 * cm1.float(), cm1)
|
|
473
|
+
c2, cm2 = ts_corr(panel.close, panel.volume, panel.mask, 4)
|
|
474
|
+
r2, rm2 = cs_rank(c2 * cm2.float(), cm2)
|
|
475
|
+
m = rm1 & rm2
|
|
476
|
+
return (r1 * r2) * m.float(), m
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
@register_legacy_factor("old_069")
|
|
480
|
+
def old_069(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
481
|
+
"""sum(max(rank(corr(ts_rank(close,5), ts_rank(volume,5), 4)), 0), 3)."""
|
|
482
|
+
cr, crm = ts_rank(panel.close, panel.mask, 5)
|
|
483
|
+
vr, vrm = ts_rank(panel.volume, panel.mask, 5)
|
|
484
|
+
m = crm & vrm
|
|
485
|
+
c, cm = ts_corr(cr, vr, m, 4)
|
|
486
|
+
rc, rcm = cs_rank(c * cm.float(), cm)
|
|
487
|
+
pos = torch.clamp(rc, min=0)
|
|
488
|
+
return ts_sum(pos, rcm, 3)
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
@register_legacy_factor("old_070")
|
|
492
|
+
def old_070(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
493
|
+
"""rank(delta(vwap, 2))."""
|
|
494
|
+
d, dm = delta(panel.vwap, panel.mask, 2)
|
|
495
|
+
return cs_rank(d * dm.float(), dm)
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
@register_legacy_factor("old_071")
|
|
499
|
+
def old_071(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
500
|
+
"""ts_rank(corr(ts_rank(close, 3), ts_rank(volume, 3), 18), 4)."""
|
|
501
|
+
cr, crm = ts_rank(panel.close, panel.mask, 3)
|
|
502
|
+
vr, vrm = ts_rank(panel.volume, panel.mask, 3)
|
|
503
|
+
m = crm & vrm
|
|
504
|
+
c, cm = ts_corr(cr, vr, m, 18)
|
|
505
|
+
return ts_rank(c * cm.float(), cm, 4)
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
@register_legacy_factor("old_072")
|
|
509
|
+
def old_072(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
510
|
+
"""rank(ewma(corr(mean(volume,40), low, 4), 1/20)) + rank(ewma(corr(rank(vwap), rank(volume), 4), 1/7))."""
|
|
511
|
+
avg, am = ts_mean(panel.volume, panel.mask, 40)
|
|
512
|
+
c1, cm1 = ts_corr(avg, panel.low, am, 4)
|
|
513
|
+
ew1, em1 = ewma(c1 * cm1.float(), cm1, alpha=1.0 / 20.0)
|
|
514
|
+
r1, rm1 = cs_rank(ew1 * em1.float(), em1)
|
|
515
|
+
rv, vm = cs_rank(panel.vwap, panel.mask)
|
|
516
|
+
rvol, volm = cs_rank(panel.volume, panel.mask)
|
|
517
|
+
m2 = vm & volm
|
|
518
|
+
c2, cm2 = ts_corr(rv, rvol, m2, 4)
|
|
519
|
+
ew2, em2 = ewma(c2 * cm2.float(), cm2, alpha=1.0 / 7.0)
|
|
520
|
+
r2, rm2 = cs_rank(ew2 * em2.float(), em2)
|
|
521
|
+
m = rm1 & rm2
|
|
522
|
+
return (r1 + r2) * m.float(), m
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
@register_legacy_factor("old_073")
|
|
526
|
+
def old_073(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
527
|
+
"""-ts_rank(ewma(Δ(vwap, 5), 1/2), 3)."""
|
|
528
|
+
d, dm = delta(panel.vwap, panel.mask, 5)
|
|
529
|
+
ew, em = ewma(d, dm, alpha=0.5)
|
|
530
|
+
r, rm = ts_rank(ew, em, 3)
|
|
531
|
+
return (-r) * rm.float(), rm
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
@register_legacy_factor("old_074")
|
|
535
|
+
def old_074(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
536
|
+
"""rank(corr(close, sum(mean(volume,30), 37), 15))."""
|
|
537
|
+
avg, am = ts_mean(panel.volume, panel.mask, 30)
|
|
538
|
+
s, sm = ts_sum(avg, am, 37)
|
|
539
|
+
c, cm = ts_corr(panel.close, s, sm, 15)
|
|
540
|
+
return cs_rank(c * cm.float(), cm)
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
@register_legacy_factor("old_075")
|
|
544
|
+
def old_075(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
545
|
+
"""rank(corr(rank(vwap), rank(volume), 5)) vs rank(corr(rank(close), rank(volume), 5))."""
|
|
546
|
+
rv, vm = cs_rank(panel.vwap, panel.mask)
|
|
547
|
+
rvol, volm = cs_rank(panel.volume, panel.mask)
|
|
548
|
+
m = vm & volm
|
|
549
|
+
c1, cm1 = ts_corr(rv, rvol, m, 5)
|
|
550
|
+
rc, rcm = cs_rank(panel.close, panel.mask)
|
|
551
|
+
c2, cm2 = ts_corr(rc, rvol, rcm & volm, 5)
|
|
552
|
+
r1, rm1 = cs_rank(c1 * cm1.float(), cm1)
|
|
553
|
+
r2, rm2 = cs_rank(c2 * cm2.float(), cm2)
|
|
554
|
+
m_out = rm1 & rm2
|
|
555
|
+
return (r1 - r2) * m_out.float(), m_out
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
@register_legacy_factor("old_076")
|
|
559
|
+
def old_076(panel: Panel) -> Tuple[Tensor, Tensor]:
|
|
560
|
+
"""rank(Δ(corr(vwap, volume, 4), 3))."""
|
|
561
|
+
c, cm = ts_corr(panel.vwap, panel.volume, panel.mask, 4)
|
|
562
|
+
d, dm = delta(c * cm.float(), cm, 3)
|
|
563
|
+
return cs_rank(d * dm.float(), dm)
|