---
title: "Current setups on a ticker"
method: GET
path: "/tickers/{symbol}/patterns"
tags: ["patterns"]
---

# Current setups on a ticker

`GET /tickers/{symbol}/patterns`

## Request

- Base URL: `https://api.tradingpal.io/api/v1`
- URL: `https://api.tradingpal.io/api/v1/tickers/{symbol}/patterns`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.tradingpal.io/oauth/authorize`, token URL `https://api.tradingpal.io/oauth/token`, scopes: `patterns`)

Returns the setups the last nightly run sees on one ticker, any ticker the nightly covers: family and direction, the two lines as dated endpoints, the trigger rule and price, stop and target, and the family and ticker track records. An empty setups list means nothing is forming; available false means the nightly has no current book for the symbol. The ticker does not need to be tracked. Setups and their ids change nightly, so do not cache them across sessions.

## Path parameters

- `symbol` string, required

## Headers

- `X-TradingPal-Client` string

## Response `200`

OK

- Patterns: The current setups on one symbol, from the last nightly run.
  - `api_version` 'v1', required: The contract version, always v1. Field names in v1 do not change, and v1 stays available at least 12 months after a v2 ships.
  - `as_of_session` string, date, nullable, required: The last trading session the data describes, as an ISO date. Setups change nightly, so say it when presenting data and do not cache setups across days. Null on routes that do not read a dated artifact (account, tickers, history, families, universe and the demo index).
  - `data_version` string, nullable: Identifier of the stored artifact the answer came from: the candidate-book generation for patterns, the sealed manifest for family records. Null when the route reads no versioned artifact.
  - `source` object, required: Who produced the data. Constant on every response.
    - `name` string: Always "TradingPal".
    - `url` string, uri: Always https://tradingpal.io.
  - `disclaimer` 'Educational breakout-pattern analysis from TradingPal, not investment advice. Past results do not guarantee future outcomes.', required: The educational-use disclaimer, constant on every response. Repeat it when presenting a setup as something the user might act on.
  - `symbol` string, required: The symbol asked for, upper-cased.
  - `available` boolean, required: True when the nightly has a current candidate book for the symbol. False when the symbol is excluded from pattern analysis or no current book exists; setups is then empty.
  - `reason` string, nullable: Why available is false, when the reason is known: not_covered means the symbol is excluded from pattern analysis. Absent when available is true, and when the nightly simply has no current book for the symbol.
  - `setups` Setup[], required: The current setups, one per eligible candidate. Empty when nothing is forming.
    - `setup_id` string, required: Identifier of this pattern occurrence in the current nightly book. Pass it as setup_id to the chart.png route. It is stable while the setup stays current and is not valid across nights, so re-read the patterns when the chart route answers setup_not_found.
    - `lineage_id` string, nullable: Key of the candidate lineage this occurrence belongs to, shared by the revisions of the same detected pattern. Null when the stored candidate carries none.
    - `page_url` string, nullable: Link that opens this setup on the TradingPal site: the Screener quick view, focused on the ticker, naming this exact setup. Free to read. Give it to the user when the chat app cannot show the chart image.
    - `symbol` string, required: Exchange symbol, upper case.
    - `interval` 'D': Bar interval. Always D: daily bars.
    - `family` 'rising_wedge' | 'falling_wedge' | 'bullish_pennant' | 'bearish_pennant' | 'triangle', required: The display family of the pattern, one of rising_wedge, falling_wedge, bullish_pennant, bearish_pennant, triangle.
    - `family_label` string: Human-readable family name, for example "Falling wedge".
    - `pattern_type` string, nullable: The detector's own pattern type, which can be more specific than family (for example a triangle subtype). Null when the artifact carries none.
    - `direction` 'bullish' | 'bearish' | 'null', nullable: The side the pattern is expected to resolve to: bullish or bearish. Null when the pattern has no single direction, such as a symmetrical triangle that carries a plan for each side.
    - `status` string, required: Lifecycle stage of the setup: forming until the trigger rule fires, in_progress once a daily close has triggered it (entered is then present). Defaults to forming when the artifact stores no stage.
    - `pattern_start` string, date, nullable: Session date of the first bar of the pattern, as an ISO date. Null when unknown.
    - `pattern_end` string, date, nullable: Session date of the last bar of the detected pattern, as an ISO date; the lines run on past it to the last session. Null when unknown.
    - `as_of_session` string, date, nullable: The session this setup is valid for, as an ISO date; the same value as the envelope's as_of_session.
    - `last_close` number, nullable: The close of the last session before as_of_session, in dollars, so a caller can place the trigger relative to price without another quote; every route reports the same value for the same setup. Null when no price is stored.
    - `price_scale` 'log': Always log: the lines are straight in log price, so draw them on a log-scale price axis.
    - `lines` object, required: The two boundary lines of the pattern.
      - `upper` object, nullable: The upper boundary. Bullish plans trigger on a daily close above it. Null when the stored pattern has no upper line.
        - `start` object: The earlier endpoint: the session and price where the line begins.
          - `date` string, date, required: Session date of the bar, as an ISO date.
          - `price` number, required: Price in dollars, rounded to four decimals.
        - `end` object: The later endpoint, at the end of the pattern geometry. The trigger price sits on the extension of the line past this point.
          - `date` string, date, required: Session date of the bar, as an ISO date.
          - `price` number, required: Price in dollars, rounded to four decimals.
        - `touch_count` integer, nullable: How many bars touched the line, as the detector counted them; the length of touches when no count is stored.
        - `touches` object[]: The bars that touched the line, in the order the detector recorded them, so a charting tool can reproduce the fit. May be empty.
          - `date` string, date, required: Session date of the touching bar, as an ISO date.
          - `price` number, nullable, required: The bar high (upper line) or low (lower line) in dollars. Null when that bar is not in the stored candle tail.
      - `lower` object, nullable: The lower boundary. Bearish plans trigger on a daily close below it. Null when the stored pattern has no lower line.
        - `start` object: The earlier endpoint: the session and price where the line begins.
          - `date` string, date, required: Session date of the bar, as an ISO date.
          - `price` number, required: Price in dollars, rounded to four decimals.
        - `end` object: The later endpoint, at the end of the pattern geometry. The trigger price sits on the extension of the line past this point.
          - `date` string, date, required: Session date of the bar, as an ISO date.
          - `price` number, required: Price in dollars, rounded to four decimals.
        - `touch_count` integer, nullable: How many bars touched the line, as the detector counted them; the length of touches when no count is stored.
        - `touches` object[]: The bars that touched the line, in the order the detector recorded them, so a charting tool can reproduce the fit. May be empty.
          - `date` string, date, required: Session date of the touching bar, as an ISO date.
          - `price` number, nullable, required: The bar high (upper line) or low (lower line) in dollars. Null when that bar is not in the stored candle tail.
    - `trigger_rule` string, nullable: The trigger rule in one sentence, chosen by direction: a daily close above the upper line, below the lower line, or through either line when the pattern carries a plan per side. Always present.
    - `plans` object[], required: One trade plan per direction the pattern can resolve in: usually one, two for a symmetrical triangle. Empty when the stored candidate has no eligible branch.
      - `direction` 'bullish' | 'bearish': The side this plan trades: bullish (a close above the upper line) or bearish (a close below the lower line).
      - `trigger_price` number, nullable: The daily close that confirms the pattern, in dollars, as of the last session. It sits on the boundary line, so it moves a little each session. Null when the stored branch has none.
      - `stop_price` number, nullable: The stop level in dollars. The backtest freezes it at entry and fills it on a touch, or at the open after an adverse gap. Null when the stored branch has none.
      - `target_price` number, nullable: The measured-move target in dollars: the pattern height projected from the trigger. Null when the stored branch has none.
    - `track_record` object, required: The backtest records behind this setup, at family scope and at ticker scope.
      - `family` StatBlock, nullable: A track record: how one pattern family resolved over the last 20 years of the served universe, or how it resolved on one ticker. Null where a record would go when none is stored; never a partial block. Never present win_rate_pct without sample_size and avg_loss_pct; quote summary whole.
        - `scope` 'family' | 'ticker': family when the record covers every ticker in the served universe, ticker when it covers one symbol.
        - `family` string: The pattern family the record is for (rising_wedge, falling_wedge, bullish_pennant, bearish_pennant, triangle).
        - `symbol` string, nullable: The ticker at ticker scope; null at family scope.
        - `win_rate_pct` number, nullable: Share of resolved trades that reached the target, as a percent (54.0 means 54%), one decimal. At ticker scope the stored rate is shrunk toward the family rate so a handful of trades cannot read as 0% or 100%; wins and losses stay raw. Never quote it without sample_size and avg_loss_pct.
        - `sample_size` integer: Number of trades in the record: the stored trade count, or wins plus losses when no count is stored. The summary sentence quotes it as resolved trades.
        - `wins` integer: Resolved trades that reached the target.
        - `losses` integer: Resolved trades that hit the stop. A bar that reaches both target and stop counts as a loss.
        - `avg_win_pct` number, nullable: Mean price move of the winning trades from entry to exit, as a percent of the entry price (positive), two decimals.
        - `avg_loss_pct` number, nullable: Mean price move of the losing trades from entry to exit, as a percent of the entry price (negative), two decimals.
        - `median_win_pct` number, nullable: Median winning move as a percent of the entry price: the typical win, less sensitive to outliers than avg_win_pct.
        - `avg_trade_pct` number, nullable: Mean price move over all resolved trades, wins and losses together, as a percent of the entry price.
        - `avg_r` number, nullable: Mean R multiple over resolved trades, where one R is the entry-to-stop distance; 0.41 means the average trade made 0.41 times its risk.
        - `expected_r` number, nullable: Per-trade expectancy in R: win rate times the average winning R plus loss rate times the average losing R. Equals avg_r when both come from the same trades.
        - `profit_factor` number, nullable: Gross R of the winning trades divided by gross R of the losing trades; above 1 means the wins outweigh the losses. Null when the record has no losses.
        - `avg_hold_bars` number, nullable: Mean number of daily bars (sessions) from entry to exit over resolved trades, one decimal.
        - `backtest_range` string[], nullable: The window the trades were taken from, as [first date, last date] in ISO format, at most the last 20 years. Null when the record carries no dates.
        - `measured` string: The measurement rule in one paragraph: how entries, stops, targets and exits are counted. Identical on every block.
        - `summary` string: One sentence with the sample size, the window, the win rate, the average win, the average loss and the median win. Quote it whole rather than picking numbers out of it.
      - `ticker` StatBlock, nullable: A track record: how one pattern family resolved over the last 20 years of the served universe, or how it resolved on one ticker. Null where a record would go when none is stored; never a partial block. Never present win_rate_pct without sample_size and avg_loss_pct; quote summary whole.
        - `scope` 'family' | 'ticker': family when the record covers every ticker in the served universe, ticker when it covers one symbol.
        - `family` string: The pattern family the record is for (rising_wedge, falling_wedge, bullish_pennant, bearish_pennant, triangle).
        - `symbol` string, nullable: The ticker at ticker scope; null at family scope.
        - `win_rate_pct` number, nullable: Share of resolved trades that reached the target, as a percent (54.0 means 54%), one decimal. At ticker scope the stored rate is shrunk toward the family rate so a handful of trades cannot read as 0% or 100%; wins and losses stay raw. Never quote it without sample_size and avg_loss_pct.
        - `sample_size` integer: Number of trades in the record: the stored trade count, or wins plus losses when no count is stored. The summary sentence quotes it as resolved trades.
        - `wins` integer: Resolved trades that reached the target.
        - `losses` integer: Resolved trades that hit the stop. A bar that reaches both target and stop counts as a loss.
        - `avg_win_pct` number, nullable: Mean price move of the winning trades from entry to exit, as a percent of the entry price (positive), two decimals.
        - `avg_loss_pct` number, nullable: Mean price move of the losing trades from entry to exit, as a percent of the entry price (negative), two decimals.
        - `median_win_pct` number, nullable: Median winning move as a percent of the entry price: the typical win, less sensitive to outliers than avg_win_pct.
        - `avg_trade_pct` number, nullable: Mean price move over all resolved trades, wins and losses together, as a percent of the entry price.
        - `avg_r` number, nullable: Mean R multiple over resolved trades, where one R is the entry-to-stop distance; 0.41 means the average trade made 0.41 times its risk.
        - `expected_r` number, nullable: Per-trade expectancy in R: win rate times the average winning R plus loss rate times the average losing R. Equals avg_r when both come from the same trades.
        - `profit_factor` number, nullable: Gross R of the winning trades divided by gross R of the losing trades; above 1 means the wins outweigh the losses. Null when the record has no losses.
        - `avg_hold_bars` number, nullable: Mean number of daily bars (sessions) from entry to exit over resolved trades, one decimal.
        - `backtest_range` string[], nullable: The window the trades were taken from, as [first date, last date] in ISO format, at most the last 20 years. Null when the record carries no dates.
        - `measured` string: The measurement rule in one paragraph: how entries, stops, targets and exits are counted. Identical on every block.
        - `summary` string: One sentence with the sample size, the window, the win rate, the average win, the average loss and the median win. Quote it whole rather than picking numbers out of it.
    - `entered` object: The fill, present only once the trigger has fired (status in_progress). Absent while forming.
      - `entry_date` string, date, nullable: Session date of the bar that triggered the setup, as an ISO date. Null when the artifact stores no entry time.
      - `entry_price` number, nullable: The entry price in dollars, recorded when the trigger fired.
      - `stop_price` number, nullable: The stop in dollars, frozen at entry.
      - `target_price` number, nullable: The target in dollars, fixed at entry.
  - `stock_facts` object, nullable: The ticker's Stock facts as the TradingPal screener's quick view shows them: price and moves, performance, momentum (EMAs, RSI, moving averages), volume and volatility, and the company. Ticker facts, so they come once per answer, not per setup. Null when the ticker has no current facts.
    - `as_of` string, nullable: When the facts were read, for example "Facts as of the Oct 6 close."
    - `sections` object[]: Groups in the quick view's order: Price, Performance, Momentum, Volume and volatility, and Company (Asset for crypto). A missing fact is left out and an empty group dropped.
      - `title` string: The group's heading.
      - `rows` object[]: The group's facts, in order.
        - `label` string, required: For example "EMA8 vs EMA21" or "RSI (14)".
        - `value` string, required: Ready to show, units included, for example "+2.5%", "$43B" or "59".
        - `tone` 'up' | 'down': up or down on signed price moves; absent on other facts.
        - `change` string: Only on the Last row: the day's change, for example "+0.40%".
        - `change_tone` 'up' | 'down': up or down for change.
  - `demo` boolean: True on the demo routes. Absent on the keyed route.
  - `next` string, nullable: On the demo routes, a sentence saying where to get a key for other tickers. Absent on the keyed route.

## Other responses

- `401`: missing_api_key (no Authorization: Bearer tp_live_… header) or invalid_api_key (unknown, revoked, or the account is inactive)
- `403`: forbidden (the account is not on Premium+, the plan with API access)
- `429`: rate_limited; wait details.retry_after_seconds

---

[API](https://skmtc.dev/tradingpal/apis/tradingpal-pattern-api.md) · [All operations](https://skmtc.dev/tradingpal/apis/tradingpal-pattern-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tradingpal/apis/tradingpal-pattern-api/revisions/e96e1f20c1ce?raw)
