Skip to content

Latest commit

 

History

History

README.md

📊 backtest-kit — Strategy Examples

A collection of production-quality backtests built with backtest-kit. Each example demonstrates a distinct signal source, entry logic, and position management approach.

screenshot

Ask DeepWiki npm TypeScript Build


🚀 Quick Start

Link to the source code

npm start -- --backtest --symbol TRXUSDT ./content/jan_2026.strategy/jan_2026.strategy.ts

📂 Strategy Index

Strategy Ticker Period Signal source Net PNL Sharpe
DOTUSDT Feb 2021 — Python EMA Crossover DOTUSDT Feb 2021 Python EMA(9)/EMA(21) crossover via WebAssembly +5.52% 0.09
BTCUSDT Apr 2024 — Polymarket Δprob BTCUSDT Apr 2024 Polymarket "yes" probability shifts on crypto-prices markets +0.63% 0.055
BTCUSDT Oct 2021 — TensorFlow Neural Network BTCUSDT Oct 2021 TensorFlow NN predicting next candle close +18.26% 0.31
BTCUSDT Dec 2025 — Pine Script Range Breakout BTCUSDT Dec 2025 Pine Script BB + range detector + volume spike +2.40% 0.06
TRXUSDT Jan 2026 — Liquidity Harvesting TRXUSDT Jan 2026 Telegram channel signals (inverted) +8.58% 1.14
BTCUSDT Feb 2026 — AI News Sentiment BTCUSDT Feb 2026 LLM forecast on live news (Tavily + Ollama) +16.99% 0.25
BTCUSDT Mar 2026 — SHORT DCA Ladder BTCUSDT Mar 2026 Fixed SHORT gravebag signal + DCA ladder up (up to 10 rungs) +37.83% 0.35
BTCUSDT Apr 2026 — DCA Ladder BTCUSDT Apr 2026 Fixed LONG moonbag signal + DCA ladder down (up to 10 rungs) +67.85% 0.12
BTCUSDT Jun 2026 — Crowd Liquidity BTCUSDT Jun 2026 TradingView ideas, elite author whitelist trained by Simulator +19.80% 0.64

🎲 Briefing


🔪 TRXUSDT January 2026 — Liquidity Harvesting

Hypothesis: The Telegram channel publishes SHORT signals with average R:R of 0.375:1 and 106% deposit at risk at 25× leverage — mathematically guaranteed to lose. Fifteen minutes before each post a volume spike appears on the chart; the TP step multipliers and T5/SL ratio are identical across all signals, indicating an algorithm. If you reverse engineer the algorithm — liquidity is yours

How it works

  1. Signals are loaded from assets/entry.jsonl — 11 real posts from the Crypto Yoda channel, exported verbatim.
  2. On each candle, getSignal checks if publishedAt matches the current minute and whether closePrice falls inside entry.from..entry.to.
  3. Counter trend entry with trailing take and no fixed TP. SL is set to -0.5%

📣 BTCUSDT June 2026 — Crowd Liquidity

Hypothesis: public TradingView ideas are mostly noise, but a handful of authors are consistently right — and their posts move enough crowd liquidity to ride. If you grid-search the author ban rule itself (minimum track record × minimum hit rate) instead of hardcoding it, the whitelist reduces to a provable elite whose every post is a tradable signal.

How it works

  1. scripts/simulator.mjs runs the framework's Simulator entity over the June ideas feed: one 5-day candle pass per idea, a 3,456-point grid (stop × trailing × hold × consensus × ban rule), flood dedupe (one idea per author per direction per 8h), default-ban for unproven authors.
  2. All three rankings (time-based Sharpe, Sortino, PnL) converge on the strictest rule — ≥5 observed ideas at ≥60% hit rate — leaving 5 authors of 167. The whitelist and winning parameters land in assets/sweep.report.BTCUSDT.json.
  3. getSignal enters on any post of a whitelisted author (N=1 — with an elite list, consensus is redundant: it fired only 4 times a month) via Position.moonbag with a 4% hard stop.
  4. Positions exit on a 2% trailing pullback from peak PnL (listenActivePing + commitClosePending) or the 5-day hold cap. Result: 10 trades, 90% WR, +19.80% on a month where BTC itself fell −20.4%.

📰 BTCUSDT February 2026 — AI News Sentiment

Hypothesis: an LLM reading live crypto/macro news every few hours can produce a directional bias (bullish / bearish / wait) that outperforms random on a sustained trending month.

How it works

  1. Every 4–8 hours, a Tavily search fetches the latest Bitcoin and macro headlines.
  2. The raw news text is passed to a local Ollama model, which returns one of bullish, bearish, or wait.
  3. getSignal opens a LONG on bullish, SHORT on bearish, and skips on wait. A conflicting forecast while a position is open triggers commitClosePending (sentiment flip).
  4. Positions exit on trailing take-profit (1% drawdown from peak) or stop-loss (1% from entry). No fixed TP target.

🪂 BTCUSDT March 2026 — SHORT DCA Ladder

Hypothesis: in a high-volatility, mean-reverting month, dollar-cost averaging into every spike upward raises the blended cost basis enough to hit a 0.5% profit target on each reversal.

How it works

  1. getSignal opens a SHORT on every new pending signal via Position.moonbag with a 25% hard stop and $100 cost.
  2. While active, commitAverageBuy fires on each ping if the current price moves outside a ±1–5% band around the last entry and fewer than 10 rungs have been added.
  3. The position closes as soon as blended portfolio PNL reaches +0.5% via commitClosePending.

🧗 BTCUSDT April 2026 — LONG DCA Ladder

Hypothesis: in a trending bull month, dollar-cost averaging into every dip lowers the blended cost basis enough to hit a 3% profit target faster and more often than a single-entry approach.

How it works

  1. getSignal opens a LONG on every new pending signal via Position.moonbag with a 25% hard stop and $100 cost.
  2. While active, commitAverageBuy fires on each ping if the current price falls outside a ±1–5% band around the last entry and fewer than 10 rungs have been added.
  3. The position closes as soon as blended portfolio PNL reaches +3% via commitClosePending.

🧠 BTCUSDT October 2021 — TensorFlow Neural Network

Hypothesis: a simple feed-forward neural network trained on normalized candle patterns every 8 hours can predict next candle close position within its high-low range, enabling profitable entries when current price is below predicted price.

How it works

  1. Every 8 hours, the strategy fetches 58 candles (50 for training + 8 for prediction), trains a neural network (8→6→4→1 architecture) on normalized data.
  2. Normalization maps each candle's close to [0,1] as (close - low) / (high - low), representing where the close sits within the candle's range.
  3. getSignal checks every 15 minutes: if currentPrice < predictedPrice, it opens a LONG via Position.moonbag with $100 entry and 1% hard stop.
  4. Positions close via trailing take-profit: when profit retraces 1% from its peak (e.g., position hits +3%, closes at +2%).

🌲 BTCUSDT December 2025 — Pine Script Range Breakout

Hypothesis: Bollinger Band breakouts from a horizontal range, confirmed by a volume spike, and produce directional signals with positive expectancy on a choppy December.

How it works

  1. Every hour Cache.fn runs btc_dec2025_range.pine on 1h candles (RSI 14) and extracts: BB bands, range boundaries, signal (±1), isRanging, volSpike.
  2. getSignal opens a LONG on signal === 1 or SHORT on signal === -1, but skips if price has already moved past the close at signal time, or if isRanging === 1.
  3. Each position uses a fixed ±2% bracket (TP and SL), no DCA, no trailing.

🎯 BTCUSDT April 2024 — Polymarket Δprob

Hypothesis: sharp daily shifts in Polymarket "yes" probability for BTC-related prediction markets reflect retail sentiment flow that precedes BTC spot movement by hours, with no look-ahead — only the timestamp and Δprob are used to choose direction.

How it works

  1. loadPolySignals reads assets/polymarket-backtest-result.json once via singleshot, aggregates to one signal per day (max |dprob| across all crypto-prices markets), and strips entryPrice/exitPrice (future-data fields).
  2. getSignal picks the most recent signal with timestamp ≤ when and rejects it if older than 1h or |dprob| < 0.10. Positive Δprob → LONG, negative → SHORT.
  3. Entry via Position.moonbag at market with a 1% hard stop and no fixed TP; listenActivePing closes on 1% trailing drawdown from peak profit, or on the 24h timeout.
  4. Result: 10 trades, 70% WR, Sharpe +0.065 — three SL hits (one per LONG on the April top) nearly cancel seven trailing-take SHORT wins on the recovery slope.

🐍 DOTUSDT February 2021 — Python EMA Crossover

Hypothesis: A classic EMA(9)/EMA(21) crossover strategy executed via Python WebAssembly can capture short-term momentum reversals on 8-hour candles with fixed bracket orders.

How it works

  1. Every 8 hours, Cache.fn runs the Python indicator (strategy.py) on 8h candles to calculate EMA(9) and EMA(21).
  2. A signal fires based on EMA crossover and 4h range midpoint confirmation: if EMA(9) > EMA(21), open LONG; otherwise SELL.
  3. Each signal opens a $100 bracket position via Position.bracket with ±2% take-profit and stop-loss.
  4. The strategy deployed $3,300 across 33 trades (all LONG), achieving +$5.52 (+0.17%) with a 63.6% win rate.