Example Strategies

Backtest a Hyperliquid Perp Strategy

A complete Hyperliquid perps backtest: leverage, maker/taker fees, and funding settled from recorded venue data, in twenty lines of kScript.

Hyperliquid trades as perpetuals: leveraged, funded, and liquidatable. A backtest that ignores those three facts will happily approve a strategy the venue would have destroyed. This walkthrough runs a trend strategy under real perps accounting: isolated margin at 10x, maker/taker fees, and funding settled from the recorded funding rates of the chart's venue.

The strategy

Open any Hyperliquid perp chart (HYPERLIQUID_FUTURES, e.g. BTC, on 1h) and paste:

hyperliquid-funding-trend.ks
//@version=2
strategy(title="HL Funding-Aware Trend", position="onchart", axis=true, initialCapital=10000, instrument="perps", leverage=10, qtyType="percentOfEquity", qtyValue=10, makerFeePercent=0.015, takerFeePercent=0.045, funding="data", slippageBps=2);

timeseries data = ohlcv(symbol=currentSymbol, exchange=currentExchange);
timeseries fast = ema(source=data.close, period=21);
timeseries slow = ema(source=data.close, period=55);

if (crossover(fast, slow)) {
  strategy.entry("Trend", "long");
}
if (crossunder(fast, slow)) {
  strategy.closeAll();
}
if (strategy.positionSize() > 0) {
  strategy.exit("Protect", fromEntry="Trend", stop=strategy.positionAvgPrice() * 0.97);
}

plotLine(value=fast, width=1, colors=["#16a34a"], label=["EMA 21"], desc=["Fast EMA"]);
plotLine(value=slow, width=1, colors=["#dc2626"], label=["EMA 55"], desc=["Slow EMA"]);

Reading the declaration, which is doing most of the perps work:

  • instrument="perps" with leverage=10: sizing commits margin, not notional. qtyValue=10 means each entry commits 10% of equity as isolated margin; the position's notional is that margin times leverage. The engine tracks the position's liquidation price from your leverage and maintenance margin, and closes you there if a bar proves or assumes the level traded. See Perps and Leverage.
  • makerFeePercent=0.015, takerFeePercent=0.045: fees route by fill type, so market entries, stops, and closeAll pay taker while limit-bound fills pay maker. Set your own tier's numbers; the declaration ships with the script so a shared backtest carries its own cost assumptions.
  • funding="data": the engine settles the actual recorded funding events from the chart's venue against your open position, debiting cash and committed margin together. This is the default; it is written out here because it is the point.

Reading the result

Three lines to check before believing the equity curve:

  1. fundingPaid in the stats: the signed funding bill. A long that looked fine gross can bleed to death through settlements while it holds; the same rules on a coarser interval hold through more settlements per trade. If part of the window had no recorded funding data, fundingUnavailableCount says so rather than pretending.
  2. liquidationCount and trades whose exit says liquidation: at 10x, a 3% protective stop and the liquidation level are uncomfortably close neighbors. If liquidations show up, the venue closed you before your stop did.
  3. The fill-precision line in the run-details popover: whether contested fills were verified with finer recorded data or settled by assumption. See Reading the Strategy Tester.

Tune it like it's real

  • Leverage down first. At 5x the liquidation level sits twice as far; watch liquidationCount go to zero before you tune anything else.
  • Widen the stop or drop the interval. Brackets arm on the bar after entry, so a tight stop on a coarse chart is exposed for one full bar. Fill Simulation covers this trade-off.
  • Run the spot twin. Duplicate the script, delete the perps params, and put both on the chart: compare mode shows exactly what leverage, fees, and funding cost you. That difference is the part most backtests never model.