NovaMarket
← All strategies

Low-volatility selection

HyperliquidRangingPerpetuals (leverage/short)Medium risk

screen the lowest-realized-vol names, then trend-follow each (pre-filter)

Track record

Return
+7.3%
Sharpe
2.62
Max DD
1.7%
AUM
$0
Created
2026-07-12
Investors
0
Pools
0
Settled days
0

Market fit

RangingSideways, mean-reverting price action
  • Buys low / sells high while price oscillates around a mean
  • Averaging against a strong one-way trend can draw down hard
Not sure where the market is headed? Browse market-neutral strategies →

Backtest (deterministic simulator)

Parameters: lookback / top_n / rebalance / fast / slow

Cross-sectional selection over a synthetic 8-symbol universe — not a promise of future returns.

"""低波筛选(Low-volatility selection)—— 前置声明式筛选器 + 每标的趋势跟随。

思路:先用筛选器从标的池里选出实现波动率最低的 top_n 个(低波因子/风险平价的选股侧),再对每个选中的
标的各自做 EMA 快慢线趋势跟随。演示"把选股作为策略前置"的用法:子类 ScreenedStrategy,框架每
rebalance_every 步重排、退出跌出榜的标的,on_symbol 只管单标的逻辑。

适用性:instrument="perp"、venues=["HYPERLIQUID"]。回测需多标的 universe feed(source="universe")。
"""
from __future__ import annotations

from ..base import StrategyBase
from ..context import StrategyContext
from ..indicators import ema
from ..registry import register
from ..screener import Screener, ScreenedStrategy


@register("低波筛选")
class LowVolSelect(ScreenedStrategy, StrategyBase):
    description = "低波筛选(前置):选实现波动最低的 top_n 标的,各自做 EMA 趋势跟随。"
    params = {"lookback": 30, "top_n": 2, "rebalance": 20, "fast": 10, "slow": 30, "slice": 8000.0}
    venues = ["HYPERLIQUID"]
    symbols: list = []
    instrument = "perp"

    def __init__(self, lookback: int = 30, top_n: int = 2, rebalance: int = 20,
                 fast: int = 10, slow: int = 30, slice: float = 8000.0) -> None:
        self.screener = Screener("volatility", lookback=int(lookback), top_n=int(top_n),
                                 direction="bottom")
        self.rebalance_every = int(rebalance)
        self.fast = int(fast)
        self.slow = int(slow)
        self.slice = float(slice)

    async def on_symbol(self, ctx: StrategyContext, sym: str) -> None:
        h = await ctx.history(sym, self.slow + 2)
        f = ema(h, self.fast)
        s = ema(h, self.slow)
        if f is None or s is None:
            return
        px = await ctx.price(sym)
        if px <= 0:
            return
        qty = self.slice / px
        await ctx.target(sym, qty if f > s else 0.0, band=qty * 0.1)  # 快线上方持有、否则离场

The full SDK and all strategies are MIT-licensed open source — backtest, paper-trade, or fork them directly.

Pools running this strategy

No pools are running this strategy yet — be the first to launch one.