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.
Files changed (54) hide show
  1. mlquant/__init__.py +18 -0
  2. mlquant/backtest/__init__.py +14 -0
  3. mlquant/backtest/engine.py +118 -0
  4. mlquant/backtest/metrics.py +95 -0
  5. mlquant/cli/__init__.py +1 -0
  6. mlquant/cli/main.py +292 -0
  7. mlquant/configs/__init__.py +1 -0
  8. mlquant/configs/small.yaml +41 -0
  9. mlquant/data/__init__.py +88 -0
  10. mlquant/data/akshare_loader.py +168 -0
  11. mlquant/data/baostock_loader.py +137 -0
  12. mlquant/data/loaders.py +125 -0
  13. mlquant/data/panel.py +206 -0
  14. mlquant/data/synthetic.py +138 -0
  15. mlquant/data/yfinance_loader.py +101 -0
  16. mlquant/features/__init__.py +42 -0
  17. mlquant/features/_factors_add.py +288 -0
  18. mlquant/features/_factors_alpha101.py +98 -0
  19. mlquant/features/_factors_best.py +177 -0
  20. mlquant/features/_factors_better.py +385 -0
  21. mlquant/features/_factors_change.py +53 -0
  22. mlquant/features/_factors_extra.py +147 -0
  23. mlquant/features/_factors_market.py +61 -0
  24. mlquant/features/_factors_old.py +563 -0
  25. mlquant/features/_factors_original.py +215 -0
  26. mlquant/features/_factors_stock.py +270 -0
  27. mlquant/features/alpha101.py +84 -0
  28. mlquant/features/bias.py +81 -0
  29. mlquant/features/legacy_factors.py +126 -0
  30. mlquant/features/market_breadth.py +190 -0
  31. mlquant/features/neutralize.py +75 -0
  32. mlquant/features/target.py +62 -0
  33. mlquant/features/tensor_factors.py +301 -0
  34. mlquant/features.py +613 -0
  35. mlquant/models/__init__.py +8 -0
  36. mlquant/models/losses.py +88 -0
  37. mlquant/models/nets.py +62 -0
  38. mlquant/portfolio/__init__.py +5 -0
  39. mlquant/portfolio/frontier.py +49 -0
  40. mlquant/portfolio/markowitz.py +144 -0
  41. mlquant/training/__init__.py +6 -0
  42. mlquant/training/augment.py +89 -0
  43. mlquant/training/dataset.py +50 -0
  44. mlquant/training/trainer.py +108 -0
  45. mlquant/utils/__init__.py +5 -0
  46. mlquant/utils/config.py +60 -0
  47. mlquant/utils/seed.py +35 -0
  48. mlquantx-0.2.5.dist-info/METADATA +108 -0
  49. mlquantx-0.2.5.dist-info/RECORD +54 -0
  50. mlquantx-0.2.5.dist-info/WHEEL +5 -0
  51. mlquantx-0.2.5.dist-info/entry_points.txt +2 -0
  52. mlquantx-0.2.5.dist-info/licenses/LICENSE +21 -0
  53. mlquantx-0.2.5.dist-info/licenses/NOTICE.md +5 -0
  54. mlquantx-0.2.5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,147 @@
1
+ """extra_* family: turnover + amount features (14 factors).
2
+
3
+ Ported from legacy Feature.py extra_001-extra_014.
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_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("extra_001")
19
+ def extra_001(panel: Panel) -> Tuple[Tensor, Tensor]:
20
+ """Delta(close_loc, 1)."""
21
+ cl = -_close_loc(panel)
22
+ return delta(cl, panel.mask, 1)
23
+
24
+
25
+ @register_legacy_factor("extra_002")
26
+ def extra_002(panel: Panel) -> Tuple[Tensor, Tensor]:
27
+ """rank(max(vwap-close, 3)) + rank(min(vwap-close, 3)) * rank(Δvolume, 3)."""
28
+ spread = panel.vwap - panel.close
29
+ mx, mm1 = ts_max(spread, panel.mask, 3)
30
+ mn, mm2 = ts_min(spread, panel.mask, 3)
31
+ dv, dm = delta(panel.volume, panel.mask, 3)
32
+ m = mm1 & mm2 & dm
33
+ mx_r, _ = cs_rank(mx, m)
34
+ mn_r, _ = cs_rank(mn, m)
35
+ dv_r, _ = cs_rank(dv, m)
36
+ out = mx_r + mn_r * dv_r
37
+ return out * m.float(), m
38
+
39
+
40
+ @register_legacy_factor("extra_003")
41
+ def extra_003(panel: Panel) -> Tuple[Tensor, Tensor]:
42
+ """open / delay(close, 1) - 1 (overnight gap)."""
43
+ prev, pm = delay(panel.close, panel.mask, 1)
44
+ out = panel.open / prev.clamp_min(1e-9) - 1.0
45
+ return out * pm.float(), pm
46
+
47
+
48
+ @register_legacy_factor("extra_004")
49
+ def extra_004(panel: Panel) -> Tuple[Tensor, Tensor]:
50
+ """Volume-weighted close-loc EWMA difference (AD oscillator)."""
51
+ cl = _close_loc(panel)
52
+ data = panel.volume * cl
53
+ x, m1 = ewma(data, panel.mask, alpha=2.0 / 9.0)
54
+ y, m2 = ewma(data, panel.mask, alpha=2.0 / 4.0)
55
+ m = m1 & m2
56
+ return (x - y) * m.float(), m
57
+
58
+
59
+ @register_legacy_factor("extra_005")
60
+ def extra_005(panel: Panel) -> Tuple[Tensor, Tensor]:
61
+ """Amount surge: amount / ts_mean(amount, 20) - 1."""
62
+ amt = _amount(panel)
63
+ avg, am = ts_mean(amt, panel.mask, 20)
64
+ out = amt / avg.clamp_min(1.0) - 1.0
65
+ return out * am.float(), am
66
+
67
+
68
+ @register_legacy_factor("extra_006")
69
+ def extra_006(panel: Panel) -> Tuple[Tensor, Tensor]:
70
+ """cs_rank of volume / mean(volume, 20)."""
71
+ avg, am = ts_mean(panel.volume, panel.mask, 20)
72
+ ratio = panel.volume / avg.clamp_min(1.0)
73
+ return cs_rank(ratio * am.float(), am)
74
+
75
+
76
+ @register_legacy_factor("extra_007")
77
+ def extra_007(panel: Panel) -> Tuple[Tensor, Tensor]:
78
+ """ewma(high-low, 2/5) / ewma(ewma(high-low, 2/5), 2/20) - range expansion."""
79
+ rng = panel.high - panel.low
80
+ sma1, m1 = ewma(rng, panel.mask, alpha=2.0 / 5.0)
81
+ sma2, m2 = ewma(sma1, m1, alpha=2.0 / 20.0)
82
+ m = m1 & m2
83
+ out = sma1 / sma2.clamp_min(1e-9)
84
+ return out * m.float(), m
85
+
86
+
87
+ @register_legacy_factor("extra_008")
88
+ def extra_008(panel: Panel) -> Tuple[Tensor, Tensor]:
89
+ """sum(max(high-delay(close,1), 0), 5) / sum(max(delay(close,1)-low, 0), 10) * 100."""
90
+ prev, pm = delay(panel.close, panel.mask, 1)
91
+ up = torch.clamp(panel.high - prev, min=0.0)
92
+ down = torch.clamp(prev - panel.low, min=0.0)
93
+ s_up, um = ts_sum(up, pm, 5)
94
+ s_down, dm = ts_sum(down, pm, 10)
95
+ m = um & dm
96
+ out = s_up * 100.0 / s_down.clamp_min(1e-9)
97
+ return out * m.float(), m
98
+
99
+
100
+ @register_legacy_factor("extra_009")
101
+ def extra_009(panel: Panel) -> Tuple[Tensor, Tensor]:
102
+ """Conditional volatility: ewma(std(close,20) * (close<=delay(close,1)), 1/5) - ewma(..., 1/20)."""
103
+ sd, sm = ts_std(panel.close, panel.mask, 20)
104
+ prev, pm = delay(panel.close, panel.mask, 1)
105
+ cond = (panel.close <= prev).float() * pm.float()
106
+ signal = sd * cond
107
+ m = sm & pm
108
+ ew1, m1 = ewma(signal, m, alpha=1.0 / 5.0)
109
+ ew2, m2 = ewma(signal, m, alpha=1.0 / 20.0)
110
+ m_out = m1 & m2
111
+ return (ew1 - ew2) * m_out.float(), m_out
112
+
113
+
114
+ @register_legacy_factor("extra_010")
115
+ def extra_010(panel: Panel) -> Tuple[Tensor, Tensor]:
116
+ """close / delay(close, 5) - 5-day momentum."""
117
+ prev, pm = delay(panel.close, panel.mask, 5)
118
+ out = panel.close / prev.clamp_min(1e-9)
119
+ return out * pm.float(), pm
120
+
121
+
122
+ @register_legacy_factor("extra_011")
123
+ def extra_011(panel: Panel) -> Tuple[Tensor, Tensor]:
124
+ """Raw amount (turnover)."""
125
+ amt = _amount(panel)
126
+ return amt * panel.mask.float(), panel.mask
127
+
128
+
129
+ @register_legacy_factor("extra_012")
130
+ def extra_012(panel: Panel) -> Tuple[Tensor, Tensor]:
131
+ """high / open."""
132
+ out = panel.high / panel.open.clamp_min(1e-9)
133
+ return out * panel.mask.float(), panel.mask
134
+
135
+
136
+ @register_legacy_factor("extra_013")
137
+ def extra_013(panel: Panel) -> Tuple[Tensor, Tensor]:
138
+ """vwap / close."""
139
+ out = panel.vwap / panel.close.clamp_min(1e-9)
140
+ return out * panel.mask.float(), panel.mask
141
+
142
+
143
+ @register_legacy_factor("extra_014")
144
+ def extra_014(panel: Panel) -> Tuple[Tensor, Tensor]:
145
+ """(high - low) / close - intraday range."""
146
+ out = (panel.high - panel.low) / panel.close.clamp_min(1e-9)
147
+ return out * panel.mask.float(), panel.mask
@@ -0,0 +1,61 @@
1
+ """Market breadth signals: cs_rank_* (6 factors).
2
+
3
+ Cross-sectional rank of daily price changes relative to previous close.
4
+ Ported from legacy/cuda_features.py.
5
+ """
6
+ from __future__ import annotations
7
+ from typing import Tuple
8
+ import torch
9
+
10
+ from ..data.panel import Panel
11
+ from .tensor_factors import cs_rank, delay
12
+ from .legacy_factors import register_legacy_factor, _amount
13
+
14
+ Tensor = torch.Tensor
15
+
16
+
17
+ @register_legacy_factor("cs_rank_close")
18
+ def cs_rank_close(panel: Panel) -> Tuple[Tensor, Tensor]:
19
+ """Cross-sectional rank of close return."""
20
+ prev, pm = delay(panel.close, panel.mask, 1)
21
+ ret = (panel.close / prev.clamp_min(1e-9) - 1.0).clamp(-0.1, 0.1)
22
+ return cs_rank(ret, pm)
23
+
24
+
25
+ @register_legacy_factor("cs_rank_open")
26
+ def cs_rank_open(panel: Panel) -> Tuple[Tensor, Tensor]:
27
+ """Cross-sectional rank of open gap."""
28
+ prev, pm = delay(panel.close, panel.mask, 1)
29
+ ret = (panel.open / prev.clamp_min(1e-9) - 1.0).clamp(-0.1, 0.1)
30
+ return cs_rank(ret, pm)
31
+
32
+
33
+ @register_legacy_factor("cs_rank_high")
34
+ def cs_rank_high(panel: Panel) -> Tuple[Tensor, Tensor]:
35
+ """Cross-sectional rank of high return."""
36
+ prev, pm = delay(panel.close, panel.mask, 1)
37
+ ret = panel.high / prev.clamp_min(1e-9) - 1.0
38
+ return cs_rank(ret, pm)
39
+
40
+
41
+ @register_legacy_factor("cs_rank_low")
42
+ def cs_rank_low(panel: Panel) -> Tuple[Tensor, Tensor]:
43
+ """Cross-sectional rank of low return."""
44
+ prev, pm = delay(panel.close, panel.mask, 1)
45
+ ret = panel.low / prev.clamp_min(1e-9) - 1.0
46
+ return cs_rank(ret, pm)
47
+
48
+
49
+ @register_legacy_factor("cs_rank_avg")
50
+ def cs_rank_avg(panel: Panel) -> Tuple[Tensor, Tensor]:
51
+ """Cross-sectional rank of vwap return."""
52
+ prev, pm = delay(panel.close, panel.mask, 1)
53
+ ret = panel.vwap / prev.clamp_min(1e-9) - 1.0
54
+ return cs_rank(ret, pm)
55
+
56
+
57
+ @register_legacy_factor("cs_rank_amount")
58
+ def cs_rank_amount(panel: Panel) -> Tuple[Tensor, Tensor]:
59
+ """Cross-sectional rank of amount."""
60
+ amt = _amount(panel)
61
+ return cs_rank(amt, panel.mask)