The hypothesis-test skill

Beginner 6 min

The most expensive mistake in testing an idea is fitting the rules to the past and believing a nice number.

The skill runs the test the way a careful researcher would: it agrees the rules with you, computes with costs, checks separately on data the idea was not fitted to, and compares against random entries. Everything the agent assumed on its own goes into the report.

How to install

Copy the skill text and paste it into the agent's chat, with this line on top:

Save this as a skill named "hypothesis-test". If you can't save skills, follow it for the rest of our conversation.
hypothesis-test.SKILL.mdClick to download
Skill text
---
name: hypothesis-test
description: Test a trading idea on ATAS history through the ATAS MCP server, with a standard report covering costs, sample size, an out-of-sample check and a comparison with random entries. Use when the user asks for a backtest, wants to test a setup, pattern or level, or wants to know how often something happens ("does absorption work at yesterday's POC", "test my idea", "how often does price return to the POC"). Not for today's signals, entry points or placing orders.
compatibility: Requires the ATAS MCP server, a crypto exchange connection, and the ability to run code for calculations. AI Connect gives the agent market data for crypto.
metadata:
  version: 0.2
  updated: 2026-11-05
---

# hypothesis-test

Test one trading idea on the history available in ATAS and report what the data supports. Reply in the user's language, briefly. Never place orders and never call the result proof that the strategy will make money.

## Hard rules

- Test only the rules the user confirmed. Do not add, remove or tighten filters, sessions or time windows on your own initiative. Ignore preferences from earlier in the conversation unless the user repeated them for this test.
- Use only ATAS data. Use external services and files only if the user asked for them in this same request, and name the source in the report.
- Compute with code (your code execution tool). Do not compute statistics in your head. If you cannot run code, say so and limit yourself to counting signals.
- Record every change and assumption in the report under "Assumptions and changes", even minor ones.
- Read numbers from tools. Never estimate them from a screenshot.

## 1. Fix the rules

Fill in the fields from the request. Ask once about anything missing and offer a default. Do not start until the user confirms.

| Field | Example | Default, if the user agrees |
|---|---|---|
| Instrument and exchange | BTCUSDT, Binance perpetual futures | None, the user must specify |
| Bar period | 5 minutes | None, the user must specify |
| Setup | Bullish engulfing touching the previous session POC | None, the user must specify |
| Entry | Open of the next bar | Open of the next bar |
| Stop | Beyond the pattern low | None, the user must specify |
| Target | 1R | None, the user must specify |
| Time exit | Close at 20:00 UTC | None, the user must specify |
| Time-of-day filter | US session hours only | None |
| Sides | Long and short | As implied by the setup |
| History | Last 60 days | Everything the chart can load |
| Costs | Commission as a % of the trade value, slippage 1 tick per side | Commission from `commissions_list`, slippage 1 tick per side |
| Funding | Include it for a perpetual futures contract | Don't include it, and record this in the assumptions |

If a rule can be read two ways, ask. "Touches the POC" needs a definition in ticks.

## 2. Get the data without touching the user's charts

1. `workspace_get_overview`, then `instruments_search` for the instrument.
2. Open a separate chart: `modules_open` with `placement: "newTab"` and `tabName: "Hypothesis test"`. Do not change the period or history depth on the user's charts.
3. Set the depth through `module_update_context` with `timeFrame: {"minutes": 5, "daysToLoad": N}`. If `loaded` is false, wait and check again. Long periods can take a while to load.
4. Read bars with `chart_get_bars`: `format: "table"`, only the `fields` you need, `count` up to 2000. Page backward with `to`. Drop the last bar if it may still be forming.
5. Session levels: add Volume Profile & TPO to the test chart (find it with `indicators_search`) and read `indicators_get_values` with `levels: 0`, up to 30 profiles per call, paging with `to`. Do not recompute the POC and value area from bars.
6. Footprint conditions: `chart_get_bars` with `footprint: true`. `footprintBars` is limited to 100 bars per call and counts from the newest returned bar, so test footprint conditions only on the stretch you can actually read, and say how far back it goes. Check the footprint first: if on most bars the volume per level is almost the same, it is evenly distributed, and such levels and POC must not be used. Say so and name the days where the data is normal.
7. A setup that can be expressed as a per-bar script can be computed with `scripts_preview`: it computes over the last 20000 bars and saves nothing. It requires Script Lab and permission to run scripts. If refused, use bars.

If ATAS doesn't return market data for the instrument, say that through AI Connect it is available for crypto, and stop until the user chooses an instrument. Replay bars and ATAS Sim are not available; do not look for workarounds.

Bar times are in UTC. Crypto trades around the clock, so sessions are defined by hours of the day. Take the chart offset from `chartTimeZoneOffset` and account for daylight saving time changes if the session is tied to New York or London.

Before computing, record the first and last bar, the number of sessions, any gaps, and whether the requested period loaded in full. If it did not, tell the user the actual period.

## 3. Compute honestly

- **No look-ahead.** A signal exists only after its bar closes. A level exists only after the session that formed it closes. Entry on the next bar or later.
- **Stop and target in the same bar:** count it as a stop and report how many trades this affected.
- **Costs:** commission and slippage on every trade, on entry and on exit. Compute a percentage commission from the trade value at the fill price. Include funding only if the user asked for it.
- **Open positions:** one position at a time unless the user said otherwise. Report how many signals were skipped because of this.
- **Contracts:** spot and perpetual futures have no rollovers. If the instrument has an expiration date, note rollovers within the period.
- **Bars are not ticks.** Entries and exits only approximate what a real order would have gotten.

## 4. Compare with something

- **Split by time before you look at the result:** the first 70% is in sample, the last 30% is the out-of-sample check. Report both parts. If out of sample has fewer than 30 trades, say that it cannot confirm anything.
- **Baseline:** the same exits and costs on random entries in the same sessions, with enough repetitions for a stable result. Show the setup next to this baseline along with the spread of the runs. If the setup's result is inside the spread, write that it does not differ from random entries. Do not call it better or worse.
- **Parameter fitting:** do not optimize unless asked. If asked, report how many variants you tried, and test the chosen one out of sample only once.

## 5. Pick a verdict

Use exactly one:

- **Not enough data:** fewer than 30 trades in total. Give the count and no conclusions about the result.
- **No edge visible:** after costs the setup is not better than the baseline, or its expectancy is not above zero.
- **Weak support:** better than the baseline in sample, but out of sample it diverges, there are too few trades, or a few trades produce most of the result.
- **Worth testing further:** better than the baseline after costs in both parts and not dependent on a few trades.

Never write "works", "profitable" or "proven". The strongest conclusion is that the idea is worth testing further.

## 6. Report

Use this format. Give results in R and as a percentage of the entry price, and in money only if the position size is known.

```
Hypothesis: <one line>
Rules as tested: <all fields>
Data: <instrument, exchange, period, first and last bar, hours, source>
Assumptions and changes: <everything you decided yourself, or "none">

                   In sample   Out of sample   Random entries
Trades
Win rate (95% range)
Average win / loss (R)
Expectancy after costs (R)
Profit factor
Max drawdown (R)
Longest losing streak

Costs per trade: <% and R>
Breakeven win rate for these exits: <%>
Stop and target in the same bar: <count>
Skipped signals: <count>
Share of profit from the 3 best trades: <%>
By month: <trades and expectancy>

Verdict: <one of the four>
Why: <two or three sentences with numbers>
What this test can't tell you: <its real limitations>
Next test: <one specific suggestion>
```

## 7. Clean up

Ask whether to keep the test chart. If not, close it with `modules_close`. Mark example trades only at the user's request (`LongPosition` / `ShortPosition`) and only on the test chart.

End with one line: this is a historical test; past results do not guarantee future results, and the decision is the trader's.

How to run it

Use hypothesis-test. BTCUSDT, 5 minutes, all loaded history, US session only, 9:30-16:00 New York time. I buy when the bar has a stack of three or more consecutive levels with a diagonal buy imbalance: ask volume at a level is 3 times the bid volume at the level below. The bar must close in the upper third of its range. Entry at the open of the next bar, stop beyond the low of the signal bar, target 1R, exit at 16:00 New York time. Commission 0.05% of the trade value per side, slippage 0.01% per side.

The agent repeats the rules and asks about anything that can be read more than one way:

Chat with the AI agent
You

Use hypothesis-test. BTCUSDT, 5 minutes, all loaded history, US session only, 9:30-16:00 New York time. I buy when the bar has a stack of three or more consecutive levels with a diagonal buy imbalance: ask volume at a level is 3 times the bid volume at the level below. The bar must close in the upper third of its range. Entry at the open of the next bar, stop beyond the low of the signal bar, target 1R, exit at 16:00 New York time. Commission 0.05% of the trade value per side, slippage 0.01% per side.

AI agent

ATAS is available. Before the test, I need you to confirm the missing details; your hypothesis-test instructions require it:

  1. Exchange and contract: the open chart is BTCUSDT Binance Futures. Use this perpetual futures contract?
  2. Stop "beyond the low": I suggest one minimum tick below the low of the signal bar.
  3. Imbalance: I suggest ask ≥ 3 × bid at the level below; with zero bid and positive ask, count it as an imbalance. Levels are adjacent minimum ticks of the instrument, without merging prices. Is that fine?
  4. Session: 09:30-16:00 New York with daylight saving time. Test every calendar day, including weekends, or Monday to Friday only? I suggest every day, with no extra filters.
  5. History: take "all loaded" to mean the depth of the current BTC chart, which I'll reproduce on a separate test chart?
  6. Execution: I suggest one position at a time, no funding; 1R is the distance from the entry price with slippage to the stop, target before costs. The last allowed entry is 15:55, any remaining position exits at 16:00.

The other rules are fixed: 5 minutes, long only, a stack of ≥3 imbalances, close in the upper third, entry at the next open, commission 0.05% and slippage 0.01% per side.

Confirm the suggested values or tell me what to change.

This is a historical test; past results do not guarantee future results, and the decision is the trader's.

After you confirm, the agent computes on a chart in a new tab, "Hypothesis test", and your charts stay as they were. In this run it stopped once more: the BTCUSDT footprint in ATAS comes in price steps of 10 USDT, while the confirmed rule spoke of a minimum tick of 0.1 USDT. You clarified that adjacent levels are 10 USDT apart and the stop goes 10 USDT below the low.

What you get

First come the verdict and the rules in the form they were tested. Then a table for the first part of the period, the second part and, for comparison, random entries: trades, win rate, expectancy after costs, drawdown. At the end comes the main part: why this verdict, what the test can't tell you and what to check next.

Full agent answer
Chat with the AI agent
You

Use the footprint step on the chart, 10 USDT: three adjacent levels are three consecutive prices with that step. Put the stop 10 USDT below the signal bar's low. Everything else as you confirmed. Go ahead.

AI agent

Hypothesis: buying after ≥3 adjacent diagonal 3:1 imbalances and a bar close in the upper third.

Rules as tested: BTCUSDT Binance Futures, perpetual contract, 5 minutes; levels 10 USDT apart, ask ≥ 3 × bid at the level below, positive ask with zero bid counts. Long at the next open; stop 10 USDT below the signal bar's low; target 1R from the entry fill. Every day, 09:30-16:00 New York with the switch to standard time; last entry 15:55, forced exit at 16:00. One position at a time. Commission 0.05%, slippage 0.01% per side; no funding.

Data: ATAS only, Binance Only Market Data. 18,113 closed bars, Sep 4, 2026 00:00 to Nov 5, 2026 21:20 UTC; 63 sessions, nothing missing. The confirmed depth is fully loaded. The footprint was read for the whole period in chunks of up to 100 bars.

Assumptions and changes: the level step and the stop offset were changed as you instructed. The forming bar is excluded. The 70/30 split point was set before the calculation: Oct 18, 2026 00:35 UTC. The upper third includes its lower boundary; a bar with zero range is not a signal. A gap through the stop fills at the open with slippage. Random baseline: 2,000 runs with the same number of entry attempts per day, a stop beyond the previous bar and the same exits; attempts with an entry below the stop are skipped. That is why the number of executed trades differs.

Metric In sample Out of sample Random entries¹
Trades 239 109 306 / 155
Win rate, 95% interval 42.3% [36.2-48.6] 40.4% [31.6-49.8] 16.7% / 17.2%
Average win / loss, R +0.51 / −1.34 +0.53 / −1.45 +0.40 / −2.49; +0.42 / −2.53
Expectancy after costs, R −0.557 −0.651 −2.013 / −2.022
Expectancy, % of entry price −0.1134% −0.1139% −0.1257% / −0.1284%
Profit factor² 0.279 0.246 0.032 / 0.034
Max drawdown, R 133.67 70.94 615.64 / 312.42
Longest losing streak 11 8 26 / 19

¹ Medians of the runs: in sample / out of sample. Central 95% of runs by expectancy: [−2.200; −1.838] R / [−2.282; −1.782] R. The average results of two halves of 1,000 runs each differed by less than 0.004R.
² From the sums of results in R.

Average win / loss as a percentage of entry: in sample +0.1823% / −0.3298%, out of sample +0.1996% / −0.3261%.

Costs per trade: on average 0.1200%, or 0.597R; by part 0.591R / 0.611R.
Breakeven win rate from the observed average wins and losses: 72.7%.
Stop and target in the same bar: 0.
Signals skipped because of an open position: 180 of 528.
Share of profit from the three best trades: 3.57% of the sum of positive results; the total result is negative, so a share of net profit doesn't apply.

Month Trades Expectancy, R % of entry
September 147 −0.484 −0.1070%
October 170 −0.659 −0.1177%
November, through the 5th 31 −0.675 −0.1220%

Verdict: No edge visible.

The setup is above the random baseline in R, but after costs the expectancy is negative in both parts: −0.557R and −0.651R. There are 109 trades out of sample; that result is negative too.

What this test can't tell you: bar-based fills don't reproduce the limit order queue, real spreads or movement inside the bar; funding is excluded. Drawdown is expressed in sums of R, without a position sizing model.

Next test: repeat the unchanged rules on a new period that hasn't been used before.

Keep the Hypothesis test 2 test chart or close it?

This is a historical test; past results do not guarantee future results, and the decision is the trader's.

There are four verdicts: not enough data, no edge visible, weak support, worth testing further. The strongest is the last one: a historical test can't go beyond it. The idea in this example got "no edge visible": it does better than random entries, but after costs the expectancy is negative in both parts of the period. Commission and slippage charged as a percentage ate 0.6 R per trade on average.

What you can set

Field What to specify If you don't
Instrument, period, setup, stop, target Your rules The agent asks
Entry When you enter Open of the next bar
Time exit When the trade must end End of the session
Session filter For example, New York only No filter
History How far back Everything the chart loads
Costs Your commission and slippage Your commission from ATAS and 1 tick per side
Funding Whether to include it for a perpetual futures contract Not included

You can also describe the condition in footprint terms, as in the example: a stack of imbalances, delta at the level where the bar closed.

What you need

  • A crypto exchange connection with footprint data, if the condition uses the footprint
  • An agent that can run code

This is a historical test. Past results do not guarantee future results, and the trading decision is yours.