Skip to content

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%

CalmVolatile

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.

Copilot proposed changesReturn −41.2%−39.9%Sharpe -0.14-0.13Max DD −66.8%−67.2%Trades 12734
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 []
Recorded runs of both versions · Synthetic data: a random-walk price series, not market prices · SPY · 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) · 200-day average, 2% band. Hypothetical results.

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.

Recorded run with the default analysis settings · Synthetic data: a random-walk price series, not market prices · SPY · 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) · default settings: 1,000 resamples, 252/63-bar walk-forward. Hypothetical results.

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.Coming soon

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

Balance $100,823 (+0.8%) after 30 calendar days, against a $108,000 target.

Final balance

100,823

P&L

+823

Days with a trade

1

BalanceMax loss floorProfit target $108k
Pass probability across resampled pathsComing soon
Recorded run · Synthetic data: a random-walk price series, not market prices · SPY · 1d · 2026-07-01 to 2026-10-08 · fills at the next bar's open, net of 1 bp slippage, $0.005/share commission ($1 minimum) · generic rule template: Generic 2-step, Phase 1. A generic template, not any firm's rules; SCUTA Quant is not affiliated with any prop firm. Hypothetical results.

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"
Real validator output for this file: Syntax validation only — not compiled or executed.

On the roadmap

  • Trade log analysis

    Coming soon

    Import a broker trade history and run the same checks on live results: verdict, Monte Carlo and prop firm rules.

  • MCP and API access

    Coming soon

    Query market data and run backtests from Claude, Cursor or your own code, through an MCP server and a REST API.