Shadowell commited on
Commit
449f353
·
verified ·
1 Parent(s): 07e48f0

Upload SuperPnL 15m realtime model package

Browse files
README.md ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ library_name: pytorch
4
+ tags:
5
+ - time-series
6
+ - finance
7
+ - crypto
8
+ - pnl
9
+ - okx
10
+ - pytorch
11
+ ---
12
+
13
+ # SuperPnL
14
+
15
+ SuperPnL 是一个面向可交易 PnL 的加密货币现货预测模型。当前上传的是第一版 OKX spot Top20 / 1min K 线模型包,推荐只使用 `15m` horizon 的实时推理结果。
16
+
17
+ Hugging Face repo:
18
+
19
+ ```text
20
+ Shadowell/SuperPnL
21
+ ```
22
+
23
+ ## 文件
24
+
25
+ ```text
26
+ model.pt
27
+ model_config.json
28
+ feature_schema.json
29
+ normalization_stats.npz
30
+ universe.json
31
+ data_contract.json
32
+ metrics_summary.json
33
+ manifest.json
34
+ superpnl_full_feature_tcn_15m_top20_20260430.tar.gz
35
+ ```
36
+
37
+ 下游服务应读取根目录文件。`.tar.gz` 是同一模型包的压缩备份。
38
+
39
+ ## 模型配置
40
+
41
+ ```text
42
+ model = full_feature_tcn
43
+ bar_size = 1m
44
+ lookback = 256
45
+ horizons = [5m, 15m]
46
+ recommended_horizon = 15m
47
+ recommended_horizon_index = 1
48
+ bar_dim = 6
49
+ feature_dim = 33
50
+ hidden_dim = 64
51
+ ```
52
+
53
+ 输入 shape:
54
+
55
+ ```text
56
+ bar: [batch, 256, 6]
57
+ features: [batch, 256, 33]
58
+ ```
59
+
60
+ 输出:
61
+
62
+ ```text
63
+ pred_ret[:, 1] -> pred_ret_15m
64
+ sigmoid(pos_logit[:, 1]) -> pos_score_15m
65
+ score_bps = pred_ret_15m * 10000
66
+ ```
67
+
68
+ ## 下载
69
+
70
+ CLI:
71
+
72
+ ```bash
73
+ hf download Shadowell/SuperPnL \
74
+ --local-dir /opt/bitpro/artifacts/superpnl \
75
+ --exclude "*.tar.gz"
76
+ ```
77
+
78
+ Python:
79
+
80
+ ```python
81
+ from huggingface_hub import snapshot_download
82
+
83
+ model_dir = snapshot_download(
84
+ repo_id="Shadowell/SuperPnL",
85
+ local_dir="/opt/bitpro/artifacts/superpnl",
86
+ ignore_patterns=["*.tar.gz"],
87
+ )
88
+ ```
89
+
90
+ ## 加载模型
91
+
92
+ 下游需要有 `SuperPnLModel` 结构定义,和训练仓库 `src/superpnl/model.py` 保持一致。源码仓库:
93
+
94
+ ```text
95
+ https://github.com/Shadowell/SuperPnL
96
+ ```
97
+
98
+ ```python
99
+ import json
100
+ from pathlib import Path
101
+
102
+ import numpy as np
103
+ import torch
104
+
105
+ from superpnl.model import SuperPnLModel
106
+
107
+ model_dir = Path("/opt/bitpro/artifacts/superpnl")
108
+
109
+ config = json.loads((model_dir / "model_config.json").read_text())
110
+ stats = np.load(model_dir / "normalization_stats.npz")
111
+ checkpoint = torch.load(model_dir / "model.pt", map_location="cpu")
112
+
113
+ model = SuperPnLModel(
114
+ bar_dim=config["bar_dim"],
115
+ feature_dim=config["feature_dim"],
116
+ num_horizons=config["num_horizons"],
117
+ hidden_dim=config["hidden_dim"],
118
+ dropout=config["dropout"],
119
+ use_features=True,
120
+ )
121
+ model.load_state_dict(checkpoint["model"])
122
+ model.eval()
123
+ ```
124
+
125
+ ## 实时推理流程
126
+
127
+ 每根 1min K 线确认后执行:
128
+
129
+ 1. 维护 `universe.json` 中 Top20 symbol 的 rolling 1min K 线窗口。
130
+ 2. 至少保留 `lookback=256` 根;建议 `warmup_bars=300`,覆盖 30m rolling 特征。
131
+ 3. 只使用 `timestamp <= t` 的已确认 K 线生成特征。
132
+ 4. 按 `feature_schema.json` 的顺序生成 `bar` 和 `features`。
133
+ 5. 使用 `normalization_stats.npz` 的训练集 mean/std 标准化。
134
+ 6. 批量推理 `[n_symbols, 256, dim]`。
135
+ 7. 读取 `recommended_horizon_index=1` 的 `pred_ret_15m`。
136
+ 8. 策略层再做 threshold、top-k、最短持仓、冷却时间、再平衡间隔和成本约束。
137
+
138
+ 不要直接用:
139
+
140
+ ```text
141
+ target_pos = 1 if pred_ret_15m > 0 else 0
142
+ ```
143
+
144
+ 这个逐分钟翻仓规则在零成本下表现好,但在真实手续费下会被高换手打穿。
145
+
146
+ ## 特征泄漏约束
147
+
148
+ - rolling / EMA / rank 都只能使用 `<= t` 的历史数据。
149
+ - 标准化参数只能使用模型包里的训练集 mean/std,不能在线重新拟合。
150
+ - 截面 rank 必须使用同一 timestamp 上已经可见的 universe 数据。
151
+ - 不能使用 future volume、future slippage、centered rolling、全样本 z-score。
152
+ - 不能用未来成交额或未来上市状态重新选择历史币池。
153
+
154
+ ## 当前实验结果
155
+
156
+ 主实验是零成本回测:
157
+
158
+ ```text
159
+ fixed_fee_bps = 0
160
+ fixed_slippage_bps = 0
161
+ threshold_bps = 0
162
+ ```
163
+
164
+ | model | horizon | zero-cost total_return | sharpe | max_drawdown | turnover | conclusion |
165
+ | --- | ---: | ---: | ---: | ---: | ---: | --- |
166
+ | full_feature_tcn | 5m | -14.49% | -3.249 | -19.33% | 0.3167 | 不可用 |
167
+ | full_feature_tcn | 15m | +62.46% | 9.099 | -5.79% | 0.2472 | 当前唯一主线 |
168
+ | full_feature_tcn | 30m | -5.80% | -1.532 | -7.95% | 0.1594 | 暂不推荐 |
169
+
170
+ 重要限制:
171
+
172
+ - 当前收益是零成本 test PnL,不能直接当作实盘净收益。
173
+ - 加入 maker/taker 成本后,逐分钟翻仓策略会被成本打穿。
174
+ - 下游必须先做低换手策略层,再用真实成本重新回测。
175
+ - 本模型不是投资建议,也不是自动实盘交易系统。
176
+
177
+ ## 推荐下游架构
178
+
179
+ ```text
180
+ BitPro 实时 1min K线
181
+
182
+ SuperPnL feature builder
183
+
184
+ SuperPnL model inference
185
+
186
+ pred_ret_15m / pos_score_15m
187
+
188
+ 低换手策略层
189
+
190
+ BitPro broker / execution
191
+ ```
192
+
193
+ 历史 prediction `.npz` 文件没有上传到 Hugging Face,也不应作为模拟盘或实盘信号源。
data_contract.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "decision_time": "At confirmed 1m bar t, generate features from bars <= t.",
3
+ "entry_exit_label_used_in_training": "label_h = log(open_{t+h+1} / open_{t+1})",
4
+ "live_prediction_output": {
5
+ "pred_ret": "model pred_ret[:, recommended_horizon_index]",
6
+ "pos_score": "sigmoid(model pos_logit[:, recommended_horizon_index])",
7
+ "score_bps": "pred_ret * 10000"
8
+ },
9
+ "minimum_live_history": {
10
+ "lookback_bars": 256,
11
+ "extra_for_rolling_features": 30,
12
+ "recommended_warmup_bars": 286
13
+ },
14
+ "not_included": [
15
+ "raw market data",
16
+ "historical test predictions",
17
+ "checkpoint optimizer state",
18
+ "orderbook/cost/liquidity features"
19
+ ]
20
+ }
feature_schema.json ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bar_feature_names": [
3
+ "open_rel",
4
+ "high_rel",
5
+ "low_rel",
6
+ "close_rel",
7
+ "volume_z_30m",
8
+ "amount_z_30m"
9
+ ],
10
+ "feature_names": [
11
+ "ret_5m",
12
+ "ret_15m",
13
+ "ret_30m",
14
+ "rsi_5m",
15
+ "rsi_15m",
16
+ "rsi_30m",
17
+ "vol_std_5m",
18
+ "vol_std_15m",
19
+ "vol_std_30m",
20
+ "ma_dev_5m",
21
+ "ma_dev_15m",
22
+ "ma_dev_30m",
23
+ "boll_z_5m",
24
+ "boll_z_15m",
25
+ "boll_z_30m",
26
+ "macd_5m_15m",
27
+ "macd_15m_30m",
28
+ "cross_section_ret_rank_5m",
29
+ "cross_section_vol_rank_5m",
30
+ "cross_section_ret_rank_15m",
31
+ "cross_section_vol_rank_15m",
32
+ "cross_section_ret_rank_30m",
33
+ "cross_section_vol_rank_30m",
34
+ "market_ret_5m",
35
+ "market_vol_5m",
36
+ "market_ret_15m",
37
+ "market_vol_15m",
38
+ "market_ret_30m",
39
+ "market_vol_30m",
40
+ "hour_sin",
41
+ "hour_cos",
42
+ "dayofweek_sin",
43
+ "dayofweek_cos"
44
+ ],
45
+ "feature_windows_minutes": [
46
+ 5,
47
+ 15,
48
+ 30
49
+ ],
50
+ "bar_size": "1m",
51
+ "normalization": {
52
+ "stats_file": "normalization_stats.npz",
53
+ "bar": {
54
+ "mean_key": "bar_mean",
55
+ "std_key": "bar_std"
56
+ },
57
+ "features": {
58
+ "mean_key": "feature_mean",
59
+ "std_key": "feature_std"
60
+ },
61
+ "fit_scope": "train split only"
62
+ },
63
+ "leakage_constraints": [
64
+ "Use only bars with timestamp <= decision timestamp t.",
65
+ "All rolling, EMA and cross-section rank features must be computed causally.",
66
+ "Do not refit normalization stats online or on validation/test/live data.",
67
+ "Do not use future volume, future slippage, centered rolling windows or future universe membership."
68
+ ]
69
+ }
manifest.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "package_name": "superpnl_full_feature_tcn_15m_top20_20260430",
3
+ "created_at_utc": "2026-04-30T17:39:37Z",
4
+ "source_run_dir": "outputs/superpnl_top20_365d_l256_h5_15_hd64_e3",
5
+ "source_cache_dir": "data/cache/okx_spot_1m_top20_365d_l256_h5_15",
6
+ "model_source": "outputs/superpnl_top20_365d_l256_h5_15_hd64_e3/full_feature_tcn.pt",
7
+ "model_sha256": "49a75f37e1552954edbaf67b3c98c21c16731654f96910cb15b0be227ba77dfd",
8
+ "package_files": {
9
+ "README.md": "6c6ee274c9099ab8cb90ae10089c3eba590e93d127d80bf9f981f2206782d334",
10
+ "data_contract.json": "8647fbc60b11a8412e8f2715528d2a47ac171a6bd8b06f82db06fafc35b8f0b0",
11
+ "feature_schema.json": "70655e6255f708111a57b44f19a0e0400a09ecea5574ff9903e8d010c3e85109",
12
+ "metrics_summary.json": "6dc204df907482352e9b4bc64b241c6ae4b9ba2f4eba623aa40d90705c9703b4",
13
+ "model.pt": "49a75f37e1552954edbaf67b3c98c21c16731654f96910cb15b0be227ba77dfd",
14
+ "model_config.json": "4d3cb1aa38a2ad684335d567e3ba044b94d3614161fb8445c745682f7a24362e",
15
+ "normalization_stats.npz": "90fb111162a35b71d4d673a974949b49a812028a94ef3242b825c793da80c3f9",
16
+ "universe.json": "402038d33a1ddc240c9003cdf0cfaa8b6851eb65b248c1902ccf67d3f06fa45c"
17
+ },
18
+ "git_note": "This package is written under artifacts/ and must not be committed."
19
+ }
metrics_summary.json ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": "full_feature_tcn",
3
+ "recommended_horizon": "15m",
4
+ "zero_cost_test_backtest": {
5
+ "total_return": 0.6245530843303917,
6
+ "annualized_return": 24.446244451050607,
7
+ "sharpe": 9.099394595727173,
8
+ "sortino": 11.139839496973575,
9
+ "max_drawdown": -0.057883877621171864,
10
+ "calmar": 422.33252946601215,
11
+ "win_rate": 0.5141435805022906,
12
+ "profit_factor": 1.043355900647199,
13
+ "turnover": 0.24720554829376007,
14
+ "average_position": 0.704076828386147,
15
+ "average_holding_minutes": 5.69603806903349,
16
+ "trade_count": 389591,
17
+ "threshold_bps": 0.0,
18
+ "fixed_fee_bps": 0.0,
19
+ "fixed_slippage_bps": 0.0,
20
+ "horizon": "15m"
21
+ },
22
+ "test_prediction_metrics": {
23
+ "mae": 0.0030127421487122774,
24
+ "rmse": 0.005572546739131212,
25
+ "direction_hit_rate": 0.48991103948019643,
26
+ "ic": 0.01989473523892385,
27
+ "icir": 0.06558929619901978,
28
+ "rank_ic": 0.019995910970156818,
29
+ "rank_icir": 0.07457593275847826
30
+ },
31
+ "baseline_backtests": {
32
+ "no_trade": {
33
+ "total_return": 0.0,
34
+ "annualized_return": 0.0,
35
+ "sharpe": 0.0,
36
+ "sortino": 0.0,
37
+ "max_drawdown": 0.0,
38
+ "calmar": 0.0,
39
+ "win_rate": 0.0,
40
+ "profit_factor": 0.0,
41
+ "turnover": 0.0,
42
+ "average_position": 0.0,
43
+ "average_holding_minutes": 0.0,
44
+ "trade_count": 0,
45
+ "horizon": "-"
46
+ },
47
+ "buy_and_hold_equal_weight": {
48
+ "total_return": 0.0656705531897448,
49
+ "annualized_return": 0.5284418475478272,
50
+ "sharpe": 0.8937807779071612,
51
+ "sortino": 1.169374365147667,
52
+ "max_drawdown": -0.17344749083328315,
53
+ "calmar": 3.0466964094381903,
54
+ "win_rate": 0.5049048845797536,
55
+ "profit_factor": 1.003842757744322,
56
+ "turnover": 1.2690516377111384e-05,
57
+ "average_position": 1.0,
58
+ "average_holding_minutes": 78799.0,
59
+ "trade_count": 20,
60
+ "fixed_fee_bps": 0.0,
61
+ "fixed_slippage_bps": 0.0,
62
+ "horizon": "-"
63
+ }
64
+ },
65
+ "warning": "Main result is zero-cost. Real-time downstream strategy must apply threshold, top-k, holding and cooldown constraints, then re-evaluate with realistic fees/slippage."
66
+ }
model.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:49a75f37e1552954edbaf67b3c98c21c16731654f96910cb15b0be227ba77dfd
3
+ size 1408034
model_config.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model_class": "superpnl.model.SuperPnLModel",
3
+ "model_name": "full_feature_tcn",
4
+ "use_features": true,
5
+ "bar_dim": 6,
6
+ "feature_dim": 33,
7
+ "num_horizons": 2,
8
+ "hidden_dim": 64,
9
+ "dropout": 0.05,
10
+ "lookback": 256,
11
+ "horizons": [
12
+ 5,
13
+ 15
14
+ ],
15
+ "horizon_index": {
16
+ "5m": 0,
17
+ "15m": 1
18
+ },
19
+ "recommended_horizon": "15m",
20
+ "recommended_horizon_index": 1,
21
+ "input_shapes": {
22
+ "bar": [
23
+ "batch",
24
+ 256,
25
+ 6
26
+ ],
27
+ "features": [
28
+ "batch",
29
+ 256,
30
+ 33
31
+ ]
32
+ }
33
+ }
normalization_stats.npz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:90fb111162a35b71d4d673a974949b49a812028a94ef3242b825c793da80c3f9
3
+ size 1117
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ torch
2
+ numpy
3
+ pandas
4
+ huggingface_hub
superpnl_full_feature_tcn_15m_top20_20260430.tar.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:82c6aa39fdc995f89a5de361fca468ab2cc2c5a43edc21bde772ced272439fe5
3
+ size 1280970
universe.json ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "symbols_superpnl": [
3
+ "BTC-USDT",
4
+ "ETH-USDT",
5
+ "DOGE-USDT",
6
+ "SOL-USDT",
7
+ "XRP-USDT",
8
+ "PEPE-USDT",
9
+ "TRX-USDT",
10
+ "XAUT-USDT",
11
+ "BIO-USDT",
12
+ "PENGU-USDT",
13
+ "PI-USDT",
14
+ "ZKJ-USDT",
15
+ "TRUMP-USDT",
16
+ "SUI-USDT",
17
+ "FIL-USDT",
18
+ "ADA-USDT",
19
+ "APE-USDT",
20
+ "CHZ-USDT",
21
+ "LINK-USDT",
22
+ "LTC-USDT"
23
+ ],
24
+ "symbols_bitpro": [
25
+ "BTC/USDT",
26
+ "ETH/USDT",
27
+ "DOGE/USDT",
28
+ "SOL/USDT",
29
+ "XRP/USDT",
30
+ "PEPE/USDT",
31
+ "TRX/USDT",
32
+ "XAUT/USDT",
33
+ "BIO/USDT",
34
+ "PENGU/USDT",
35
+ "PI/USDT",
36
+ "ZKJ/USDT",
37
+ "TRUMP/USDT",
38
+ "SUI/USDT",
39
+ "FIL/USDT",
40
+ "ADA/USDT",
41
+ "APE/USDT",
42
+ "CHZ/USDT",
43
+ "LINK/USDT",
44
+ "LTC/USDT"
45
+ ],
46
+ "symbol_mapping": {
47
+ "BTC/USDT": "BTC-USDT",
48
+ "ETH/USDT": "ETH-USDT",
49
+ "DOGE/USDT": "DOGE-USDT",
50
+ "SOL/USDT": "SOL-USDT",
51
+ "XRP/USDT": "XRP-USDT",
52
+ "PEPE/USDT": "PEPE-USDT",
53
+ "TRX/USDT": "TRX-USDT",
54
+ "XAUT/USDT": "XAUT-USDT",
55
+ "BIO/USDT": "BIO-USDT",
56
+ "PENGU/USDT": "PENGU-USDT",
57
+ "PI/USDT": "PI-USDT",
58
+ "ZKJ/USDT": "ZKJ-USDT",
59
+ "TRUMP/USDT": "TRUMP-USDT",
60
+ "SUI/USDT": "SUI-USDT",
61
+ "FIL/USDT": "FIL-USDT",
62
+ "ADA/USDT": "ADA-USDT",
63
+ "APE/USDT": "APE-USDT",
64
+ "CHZ/USDT": "CHZ-USDT",
65
+ "LINK/USDT": "LINK-USDT",
66
+ "LTC/USDT": "LTC-USDT"
67
+ },
68
+ "selection_note": "OKX spot *-USDT non-stablecoin Top20 at download time, requiring full 365d 1m history coverage. Keep this universe fixed for reproducible inference/backtests."
69
+ }