feat(backtest): v4.2 新增 FSL 分水岭指标策略(单标的/组合/寻优)

- MyTT.py: 新增 FSL(CLOSE, VOL, CAPITAL) 分水岭指标
  - SWL = (EMA(C,5)*7 + EMA(C,10)*3) / 10
  - SWS = DMA(EMA(C,12), MAX(1, 100*SUM(VOL,5)/(3*CAPITAL)))
    MIN(A,1.0) 模拟通达信 DMA(X,A) 内部钳制 A<=1 的语义
- MyTT.pyi: 补 FSL 类型 stub(CI mypy 用 .pyi 校验)
- strategies/builtin.py: 注册 FslStrategy(SWL/SWS 金叉死叉)
  capital 作为 Param 暴露流通股本输入
- strategies/presets.py: fsl 寻优网格(4 档 capital)
- tests: 注册表断言加 fsl,阈值 18→19
This commit is contained in:
GitHub
2026-07-09 18:42:00 +08:00
parent 8bf4ffb322
commit 052119e6ae
5 changed files with 60 additions and 1 deletions
+12
View File
@@ -15,6 +15,7 @@
# V3.3 2023-11-09 新增 SIN,COS,TAN序列处理的三角函数
# V4.0 2026-06-02 handsomejustin 新增 ZHUOYAO,BIAS_SIGNAL两个自创函数
# V4.1 2026-06-14 新增 SAR(抛物线转向), VWAP(成交量加权均价), AROON(阿隆指标); 注册 FK
# V4.2 2026-07-09 新增 FSL(分水岭指标)
# 以下所有函数如无特别说明,输入参数S均为numpy序列或者列表list,N为整型int
# 应用层1级函数完美兼容通达信或同花顺,具体使用方法请参考通达信
@@ -559,4 +560,15 @@ def AROON(HIGH, LOW, N=25): # 阿隆指标:趋势启动时机识别(N周期
return RD(AROON_UP), RD(AROON_DOWN), RD(OSC)
def FSL(CLOSE, VOL, CAPITAL): # 分水岭指标:多空趋势强弱分界(SWS含换手率动态平滑)
# SWL = (EMA(C,5)*7 + EMA(C,10)*3) / 10 : 5日/10日指数均值的加权合成
SWL = (EMA(CLOSE, 5) * 7 + EMA(CLOSE, 10) * 3) / 10
# SWS = DMA(EMA(C,12), MAX(1, 100*SUM(VOL,5)/(3*CAPITAL)))
# 平滑因子 = 5日成交量换手率放大值,CAPITAL 为流通股本
A = MAX(1, 100 * (SUM(VOL, 5) / (3 * CAPITAL)))
A = MIN(A, 1.0) # 模拟通达信 DMA(X,A) 内部钳制 A<=1,避免序列因子越界发散
SWS = DMA(EMA(CLOSE, 12), A)
return RD(SWL), RD(SWS)
# 望大家能提交更多指标和函数 https://github.com/mpquant/MyTT
+5
View File
@@ -105,6 +105,11 @@ def AROON(
N: int = ...,
) -> tuple[NDArray, NDArray, NDArray]: ...
def FK(CLOSE: npt.ArrayLike) -> NDArray: ...
def FSL(
CLOSE: npt.ArrayLike,
VOL: npt.ArrayLike,
CAPITAL: float,
) -> tuple[NDArray, NDArray]: ...
# ── Utility Functions ────────────────────────────────────────────────────────
@@ -25,6 +25,7 @@ from easy_tdx.MyTT import (
DPO,
EMA,
EMV,
FSL,
KDJ,
KTN,
MA,
@@ -552,3 +553,38 @@ class AtrBreakoutStrategy(ParametrizedStrategy):
self.buy()
elif close <= lower and self.position["size"] > 0:
self.sell()
# ── FSL 分水岭指标 ────────────────────────────────────────────────────────────
@register_strategy(
name="fsl",
label="FSL 分水岭",
description="SWL 上穿 SWS 买入(多头占优),SWL 下穿 SWS 卖出(空头占优)。",
)
class FslStrategy(ParametrizedStrategy):
"""FSL 分水岭 SWL/SWS 金叉死叉。"""
params = [
Param(
"capital",
float,
default=1e8,
min_value=1e6,
max_value=1e12,
label="流通股本(股)",
),
]
def init(self) -> None:
self.swl, self.sws = self.I(FSL, self.data.close, self.data.vol, self.p["capital"])
self.gold = self.I(CROSS, self.swl, self.sws)
self.dead = self.I(CROSS, self.sws, self.swl)
def next(self) -> None:
i = self._bar_index
if self.gold[i]:
self.buy()
elif self.dead[i] and self.position["size"] > 0:
self.sell()
@@ -93,6 +93,11 @@ STRATEGY_PRESETS: dict[str, dict[str, list[Any]]] = {
"dpo": {
"m1": [15, 20, 30],
}, # 3
# ── 分水岭类 ─────────────────────────────────────────────────────────────
"fsl": {
# capital 仅作粗档扫描(1千万/1亿/10亿股),覆盖小盘→大盘
"capital": [1e7, 1e8, 1e9, 1e10],
}, # 4
}
+2 -1
View File
@@ -59,7 +59,8 @@ def test_registry_has_builtin_strategies():
assert "boll_breakout" in names
assert "rsi_reversal" in names
assert "kdj_cross" in names
assert len(names) >= 18
assert "fsl" in names
assert len(names) >= 19
def test_strategy_schema_serialization():