qka 2.4.4.dev2__py3-none-any.whl → 2.4.5.dev2__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.
- qka/core/data.py +36 -6
- {qka-2.4.4.dev2.dist-info → qka-2.4.5.dev2.dist-info}/METADATA +1 -1
- {qka-2.4.4.dev2.dist-info → qka-2.4.5.dev2.dist-info}/RECORD +6 -6
- {qka-2.4.4.dev2.dist-info → qka-2.4.5.dev2.dist-info}/WHEEL +0 -0
- {qka-2.4.4.dev2.dist-info → qka-2.4.5.dev2.dist-info}/entry_points.txt +0 -0
- {qka-2.4.4.dev2.dist-info → qka-2.4.5.dev2.dist-info}/licenses/LICENSE +0 -0
qka/core/data.py
CHANGED
|
@@ -1248,10 +1248,20 @@ class Data():
|
|
|
1248
1248
|
return self._compute_qka_factor_cols(df, qka_specs)
|
|
1249
1249
|
|
|
1250
1250
|
def _compute_qka_factor_cols(self, df, qka_specs, symbols=None):
|
|
1251
|
-
"""在已合并的 DataFrame 上计算 qka 内置指标。
|
|
1251
|
+
"""在已合并的 DataFrame 上计算 qka 内置指标。
|
|
1252
|
+
|
|
1253
|
+
因子定义的末位可以放一个 dict,作为**这一个因子自己的选项**,
|
|
1254
|
+
只作用于它的计算,不影响别人、也不影响原始 returns:
|
|
1255
|
+
('qka.alpha', 250, {'max_abs_return': 0.5})
|
|
1256
|
+
超限的那天在因子眼里记空 —— 含这一天的滚动窗口就凑不满样本,
|
|
1257
|
+
因子自然算不出来(作废),原始行情和 returns 一个字不动。
|
|
1258
|
+
"""
|
|
1252
1259
|
for col_key, spec in qka_specs:
|
|
1253
1260
|
fn_name = spec[0].split('.', 1)[1] if spec[0].startswith('qka.') else spec[0]
|
|
1254
1261
|
args = list(spec[1:])
|
|
1262
|
+
# 末位 dict = 该因子的选项;不是 dict 就照旧当位置参数传下去
|
|
1263
|
+
opts = args.pop() if args and isinstance(args[-1], dict) else {}
|
|
1264
|
+
lim = opts.get('max_abs_return')
|
|
1255
1265
|
|
|
1256
1266
|
try:
|
|
1257
1267
|
fn = getattr(indicator, fn_name)
|
|
@@ -1262,8 +1272,15 @@ class Data():
|
|
|
1262
1272
|
# 为每只股票计算
|
|
1263
1273
|
for symbol in (symbols if symbols is not None else self.symbols):
|
|
1264
1274
|
col = f'{symbol}|{col_key}'
|
|
1275
|
+
work = df
|
|
1276
|
+
if lim:
|
|
1277
|
+
# 净化副本:只把这只票和基准的涨降幅超限处记空,别的列原样
|
|
1278
|
+
work = df.copy()
|
|
1279
|
+
for c in (f'{symbol}|returns', 'benchmark|returns'):
|
|
1280
|
+
if c in work.columns:
|
|
1281
|
+
work[c] = work[c].where(work[c].abs() <= lim)
|
|
1265
1282
|
try:
|
|
1266
|
-
df[col] = fn(
|
|
1283
|
+
df[col] = fn(work, symbol, *args)
|
|
1267
1284
|
except ValueError as e:
|
|
1268
1285
|
logger.warning(f"计算 {col_key} 失败: {e}")
|
|
1269
1286
|
df[col] = np.nan
|
|
@@ -1407,14 +1424,27 @@ class Data():
|
|
|
1407
1424
|
|
|
1408
1425
|
@staticmethod
|
|
1409
1426
|
def _spec_payload(spec):
|
|
1410
|
-
"""把一份因子定义转成可稳定序列化的结构;认不出返回 None。
|
|
1427
|
+
"""把一份因子定义转成可稳定序列化的结构;认不出返回 None。
|
|
1428
|
+
|
|
1429
|
+
末位的 dict 是「该因子自己的选项」(如 max_abs_return),也要进指纹 ——
|
|
1430
|
+
选项变了,算出来的值就不一样,缓存必须跟着失效。
|
|
1431
|
+
"""
|
|
1411
1432
|
if callable(spec):
|
|
1412
1433
|
src = _callable_source(spec)
|
|
1413
1434
|
return None if src is None else {'fn': src}
|
|
1414
1435
|
if isinstance(spec, (list, tuple)):
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1436
|
+
items = []
|
|
1437
|
+
for x in spec:
|
|
1438
|
+
if isinstance(x, dict):
|
|
1439
|
+
if not all(isinstance(k, str) and isinstance(v, (str, int, float, bool))
|
|
1440
|
+
for k, v in x.items()):
|
|
1441
|
+
return None
|
|
1442
|
+
items.append({k: x[k] for k in sorted(x)})
|
|
1443
|
+
elif isinstance(x, (str, int, float, bool)):
|
|
1444
|
+
items.append(x)
|
|
1445
|
+
else:
|
|
1446
|
+
return None
|
|
1447
|
+
return items
|
|
1418
1448
|
return None
|
|
1419
1449
|
|
|
1420
1450
|
def _factor_cache_path(self, name: str, symbol: str) -> Path:
|
|
@@ -5,7 +5,7 @@ qka/core/accessor.py,sha256=iEZrteVe8nqv3s5Va2l3Vz50N2S6X0IOElKq9Ik3Wno,2893
|
|
|
5
5
|
qka/core/analysis.py,sha256=EXCO4qhzd2av5Yb4jihcNji1V-VFPOceUHKtg-q8bLs,11142
|
|
6
6
|
qka/core/backtest.py,sha256=kzMAFbyGFvGE--Qypiot6wAp0jTiEsOPbaPd8Zs3o1M,13541
|
|
7
7
|
qka/core/broker.py,sha256=FxeHh9qZ9M6FNFLd8EXwztA4kmC9zZzkrXin2hdVFa4,9662
|
|
8
|
-
qka/core/data.py,sha256=
|
|
8
|
+
qka/core/data.py,sha256=VKXgFLsUJnD-36yYWb0Na84kqeJWr3_vSetG3mJCMGE,95301
|
|
9
9
|
qka/core/indicator.py,sha256=OId8bgYFCzDgjPr27rb6zHYxkPYX0XrjlWylGSQ2KCU,6447
|
|
10
10
|
qka/core/report.py,sha256=TaZoxWk7ZIPLhA9Ss9UOmxWY2ymzKJRUnxSzmyPcBTI,22386
|
|
11
11
|
qka/core/simulate.py,sha256=bdThckUFj0Y3GyAj5ahLIGv3HetJFTbyxbEcX2SUKn0,2915
|
|
@@ -21,8 +21,8 @@ qka/skills/qka/references/broker.md,sha256=wr62v1asRM-wBdsADIsB406eXm_ENYcrwGMAN
|
|
|
21
21
|
qka/skills/qka/references/data.md,sha256=6mL44eGOk_xXLqQ62Wmv1DFYcXn3kayYWYWMd8-hFOk,28857
|
|
22
22
|
qka/skills/qka/references/sizing.md,sha256=3SsX2ddQoHjE177dberW0Q7wYxW-M_2DG_-sV3CCo9A,656
|
|
23
23
|
qka/skills/qka/references/strategy.md,sha256=-6xa_oigTTj77Siity5bTC5MbdF3UKfld9imnevlAAc,4455
|
|
24
|
-
qka-2.4.
|
|
25
|
-
qka-2.4.
|
|
26
|
-
qka-2.4.
|
|
27
|
-
qka-2.4.
|
|
28
|
-
qka-2.4.
|
|
24
|
+
qka-2.4.5.dev2.dist-info/METADATA,sha256=GGgy1pKolxfDgtl_g9oFQYzlubVc_56mk2hw_FUExrk,7545
|
|
25
|
+
qka-2.4.5.dev2.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
26
|
+
qka-2.4.5.dev2.dist-info/entry_points.txt,sha256=quG9zg-rOKKtbg-6FiXkoxkUUTMltMBD0hZ0QUnJ6RM,37
|
|
27
|
+
qka-2.4.5.dev2.dist-info/licenses/LICENSE,sha256=3iIG35SnJNF11yIzm3vxa2QUvy9SS5rktM3O1DL2vqM,1075
|
|
28
|
+
qka-2.4.5.dev2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|