Tutorial
This is the whole product in one page. If you read nothing else, read this — it is written to be sufficient on its own.
It takes about fifteen minutes end to end. Every step states what you do, what you should see, and what it means. Where a step hides a mechanism, a collapsible panel underneath carries the detail.
What you are actually doing
The product does one thing repeatedly, at three levels of ambition:
| Level | What happens | Cost |
|---|---|---|
| Backtest | One script, one set of parameters, one result | Seconds |
| Optimize | The same script run over hundreds or thousands of parameter sets, in parallel | Minutes |
| Analyse | Read the finished run: what the best result was, and whether it is trustworthy | Seconds |
Everything below is those three verbs, in that order.
Step 1 — Start the workspace
npm run devOpen http://localhost:8080 .
You should see: a dark trading workspace — a market chart on the left, a Pine editor on the right, a slim control bar across the top.
Do you need to sign in? No.
The application is a static page: IndicaView serves it over the network, and all computation happens in your browser or in Web Workers it spawns. There is no server-side application logic, and the market data it reads is public and keyless.
A Sign in control exists, and it is entirely optional. Signing in opens a My Account area for your display name and contact phone. It does not gate the chart, the optimizer or the analysis, and leaving it signed out costs you nothing but the profile. See Authentication.
Step 2 — Choose a market
Use the controls in the top bar. The symbol picker’s search button queries Binance and ranks pairs by 24-hour volume, so liquid markets appear first. Timeframes are grouped, with a custom field for anything unusual.
You should see: the chart redraw with candles.
Step 3 — Load a strategy
Pick one from the strategy selector. Each file in app/strategies/ appears there.
For this tutorial use ema_cross.pine.
You should see: Pine source in the editor, and the parameters it declares listed in the parameter area.
Step 4 — Read the parameters before you run anything
The editor shows a parameter for every input.* call in the script. ema_cross.pine has
four:
| Parameter | Meaning | Default |
|---|---|---|
| Fast EMA length | Lookback of the fast moving average | 9 |
| Slow EMA length | Lookback of the slow moving average | 21 |
| RSI length | Lookback for the RSI filter | 14 |
| ATR length | Lookback used to size stops and targets | 14 |
These four are the search space. Nothing else about the script changes between trials. This is the single most important idea in the product: you are not searching over strategies, you are searching over this list of numbers.
How a parameter becomes a searchable dimension
The optimizer reads the input.* declarations straight out of the Pine source.
A declaration whose default value is a number becomes a numeric dimension; a boolean becomes
a two-way choice; a list of choices becomes a categorical dimension.
The conventional way to write a tunable parameter in Pine is with the value first:
Two Pine conventions the tooling depends on
// 1. Positional default — the value comes first, and that is what marks it
// as tunable. The optimiser reads the first argument.
fast_len = input.int(9, "Fast EMA Length")
atr_len = input.int(14, "ATR Length") // two spaces — still fine here
// 2. Emit the signal as data, not only as a picture.
plotshape(long_signal, "Buy", shape.triangleup, location.belowbar, color.green)
plot(long_signal ? 1 : 0, "Long Signal", display = display.none) // ← this lineThe hidden plot is what a reconstruction reads. The visible
plotshape is only for you. Ship both.
Step 5 — Run one backtest
Press Ctrl + Enter, or use the Run button.
You should see: a lower panel with three tabs — Performance, Trades Analysis, Trades Log — plus a metric card row and an equity curve.
Full explanation, including how the reconstruction picks fill prices and applies costs, in Engines — real fills vs synthetic.
Step 6 — Read the result
Look at three numbers:
- Net profit — did it make anything at all, over the period?
- Max drawdown — how much of the peak was given back at worst? A strategy that is up 20% and gave back 60% is a different animal from one that is up 5% and gave back 1%.
- Trade count — how many times the logic actually fired. A great-looking result on four trades is noise.
If trade count is very low, the result is not informative yet. That is normal, and it is exactly what the optimizer exists to fix.
Step 7 — Open the optimizer
Switch to the Optimizer workspace. The chart and editor stay mounted; the lower panel is replaced.
The configuration column shows the four dimensions from Step 4, already discovered from your source. You choose:
| Control | What to pick |
|---|---|
| Method | Start with TPE — it is the default and the best general-purpose choice |
| Budget | Trials to run. Start with 100 while you are learning |
| Seed | Leave it fixed. A fixed seed makes the run reproducible |
You should see: a grid size — how many distinct parameter sets the space contains — and an estimate of how many trials remain.
Which method should I actually pick?
There are seven, and the differences matter. The short answer:
- TPE — the default, and the right answer for almost every strategy. It learns a probability model of “where the good results are” and samples from it. Use this unless you have a reason not to.
- Grid — when the space is small (a few thousand combinations or fewer) you can simply test everything. Exhaustive beats clever at small sizes.
- Random — a sane baseline. If Random finds the optimum, your parameter space is probably not doing much work.
- SA — useful when you believe the landscape is smooth and the optimum is a broad basin.
- GA — slowest to show a useful result on small spaces. Manual selection only.
- Brute — overlaps Grid; treated separately so the UI can express intent.
The reasoning behind every one of these, and the exact mechanics, is in Algorithms.
Step 8 — Launch the run
Click ▶ Run again. Configuration locks, and the run captures the source, the bars and the search space it was given — so the result is attributable to exactly this configuration.
You should see: a results table filling in progressively. Trials complete in parallel across your CPU cores.
| Control | What it does |
|---|---|
| Pause / Resume | Stops handing out work, keeps the run alive |
| Stop | Terminates. Completed trials are kept; only the in-flight trial is discarded |
| Run again | A fresh run. Clicking Run while one is active is ignored, not queued |
Step 9 — Read the results table
Sort by profit factor or your chosen metric. The table lists every completed trial with its parameters and metrics.
Three questions, in order:
- Where is the best trial? Click it. Note its parameters.
- Is it an outlier or a trend? A single spike in an otherwise flat distribution is usually luck. A broad cluster of good results is usually real.
- Do the parameters make sense? If your “best” result requires
fast_len: 3, slow_len: 58, the optimiser has probably found noise, not an edge. You are looking for regions that are stable, not a single maximum.
Why a single best result is the wrong thing to trust
With 1 000 trials, the best result is the maximum of 1 000 noisy samples. Even a strategy with no real edge at all will produce an impressive-looking best trial purely by chance. This is the multiple-comparisons problem, and it is the single biggest way people fool themselves with an optimiser.
What helps: look at the distribution of results rather than the maximum, prefer parameter regions where many neighbours also scored well, and re-run with a different seed to see whether the same region keeps winning. The Analysis workspace is built for exactly this.
Step 10 — Open the analysis
Click Open analysis. This replaces the popup with a full Analysis workspace for the current run.
Three things worth doing straight away:
| Section | Use it to answer |
|---|---|
| Trials | How many trials ran, and how good were the top ten? |
| Parameter Analysis | Which parameters actually mattered? |
| Performance and Risk | What does the best trial’s equity curve actually look like? |
Then Open in Snipe to inspect one specific trial in detail — this opens the exact trial you had selected, not just the run it came from.
Step 11 — Export
The results panel offers three actions, all inside a Result actions menu (⋮):
| Action | What you get |
|---|---|
| CSV | The trials you can currently see — it honours your filters and sort |
| JSON | The complete run, regardless of what is on screen |
| Share card | A single PNG summarising the run, ready to post |
CSV respects the filters and sorting you have applied — use it for “the top ten under these criteria”. JSON always contains the complete run regardless of what is on screen — use it when you want to re-analyse offline. The share card is an image rather than data; it never includes your Pine source or the winning parameter values.
Full detail in Sharing & export.
Where to go from here
| If you want to… | Go to |
|---|---|
| Understand the algorithms properly | Algorithms |
| See a full worked example, start to finish | Workflow |
| Know what your numbers mean | Engines — real vs synthetic |
| Know what this tool does not prove | Limitations |
| Write your own strategy | Strategies |