Build, backtest, fix.
Before you trade it.
Ask a research question. SCUTA writes the code, runs the backtest and reports what held up, and what did not.
Synthetic data · every example on this page runs on a random-walk price series, not market prices
class Strategy: """Trend following: long while the 20-bar SMA is above the 50-bar SMA.""" def __init__(self): self.fast = 20 self.slow = 50 self.allocation = 0.95 # fraction of cash to invest on entry def on_bar(self, context, bar): closes = [b.close for b in context.history[-(self.slow - 1):]] + [bar.close] if len(closes) < self.slow: return [] fast_ma = sum(closes[-self.fast:]) / self.fast slow_ma = sum(closes[-self.slow:]) / self.slow pos = context.position.qty if fast_ma > slow_ma and pos == 0: qty = int(context.cash * self.allocation // bar.close) return [{"side": "buy", "qty": qty}] if qty > 0 else [] if fast_ma < slow_ma and pos > 0: return [{"side": "sell", "qty": pos}] return []Results
6,202 daily bars, AAPL, 2003-01-01 to 2026-10-08Fills at the next bar's open, 1 bp slippage, $0.005/share commission ($1 minimum), $100,000 startsma 20/50 return −28.6% max DD −81.2% 75 tradesRegime: 20-day realized vol at the prior close vs its median to datecalm 2,853 sessions return −51.9% −6.5% a yearvolatile 3,310 sessions return +48.6% +3.2% a year
Synthetic data: a random-walk price series, not market prices · AAPL · 1d · 2003-01-01 to 2026-10-08 · fills at the next bar's open, net of 1 bp slippage, $0.005/share commission ($1 minimum) · 20-day realized volatility split at its median to date
The trend model lost in calm markets and made its money in volatile ones
The 20/50 crossover compounded −52% over 2,853 calm sessions (−6% a year) and +49% over 3,310 volatile ones (+3% a year), with the regime read at the prior close.
Return, calm sessions
−51.9%
Return, volatile sessions
+48.6%
Recorded runs of the SCUTA engine on synthetic data, replayed. Every number is after slippage and commission, with orders filled at the next bar's open. Hypothetical results, not a forecast.
From a question to a result
Ask in plain English. The agent reads the docs, writes the strategy, runs the backtest and reports the numbers, including the ones that argue against it.
Writes, backtests and repairs the code
Describe a change in plain English. Copilot edits the file, backtests it with your run settings and shows the diff with its numbers next to your last run's. Nothing changes until you accept it.
When a run fails, it reads the error, fixes the code and runs it again, up to three attempts.
In the recorded edit: Trades went from 127 to 34; max drawdown from −66.8% to −67.2%; total return from −41.2% to −39.9%.
Add the 2% band and compare trade count and drawdown.
class Strategy: """Hold SPY while it closes above its 200-day average, cash below it.""" def __init__(self): self.window = 200Added: self.band = 0.02 self.allocation = 0.99 def on_bar(self, context, bar): closes = [b.close for b in context.history[-(self.window - 1):]] + [bar.close] if len(closes) < self.window: return [] average = sum(closes) / self.window pos = context.position.qtyRemoved: if bar.close > average and pos == 0:Added: if bar.close > average * (1 + self.band) and pos == 0: qty = int(context.cash * self.allocation // bar.close) return [{"side": "buy", "qty": qty}] if qty > 0 else []Removed: if bar.close < average and pos > 0:Added: if bar.close < average * (1 - self.band) and pos > 0: return [{"side": "sell", "qty": pos}] return []A second opinion on every backtest
Monte Carlo resampling shows the range of outcomes the same trades could have produced. Walk-forward re-tests the same fixed parameters on later windows, with the run's fills and costs, and compares each window with buy and hold, dividends reinvested. It does not re-optimize parameters. The verdict combines them into a 0–100 score, graded A to F, with the flags that drove it.
A high return does not earn a high grade on its own. The strategy shown returned −21.0% and grades F, flagged for poor walk forward, elevated tail risk.
Test a challenge before you pay for one
Replay a backtest against a challenge's rules, day by day: profit target, static or trailing max loss, daily loss limit, minimum trading days, calendar-day time limit and consistency. Start from a generic template or enter your own rules, and see whether it passes, breaches a rule or runs out of time.
The probability of passing across resampled paths is next.
Prop firm simulatorGeneric 2-step · Phase 1
- Profit target
- +8.0%
- Max loss
- 10% static
- Daily loss
- 5%
- Time limit
- 30 calendar days
Expired before the target
Final balance
100,823
P&L
+823
Days with a trade
1
Bring your Pine Script, NinjaScript or EasyLanguage
Keep strategies written for other platforms in the same project. Today SCUTA checks their syntax: brackets, declarations and version directives. It does not compile or backtest them.
- Pine Script
- NinjaScript
- EasyLanguage
- PowerLanguage
Pine Script · syntax validation only
//@version=5strategy("Three down days", overlay=true)hold = input.int(5, "Sessions to hold")downs = close < close[1] and close[1] < close[2] and close[2] < close[3]if downs and strategy.position_size == 0 strategy.entry("Long", strategy.long)if strategy.position_size > 0 and bar_index - strategy.opentrades.entry_bar_index(0) >= hold strategy.close("Long"Syntax issues
L11: Unclosed '('
On the roadmap
Trade log analysis
Import a broker trade history and run the same checks on live results: verdict, Monte Carlo and prop firm rules.
MCP and API access
Query market data and run backtests from Claude, Cursor or your own code, through an MCP server and a REST API.