id: pattern name: Pattern Skill tagline: Pattern description: Detects chart patterns in OHLC data from natural-language hypotheses or visual chart selections. version: 1.0.0 author: Vibe Trade Core category: analysis icon: chart-line color: "#ff6b00"
Tools this skill is allowed to invoke. Each id must exist in the central
tool catalog (skills/tools.py). The frontend enforces this allowlist — a
skill that emits a tool_call for an id not listed here is rejected.
tools:
- chart.pattern_selector
- chart.highlight_matches
- chart.draw_markers
- chart.focus_range
- script_editor.load
- script_editor.run
- bottom_panel.activate_tab
- bottom_panel.set_data
- notify.toast
Bottom panel tabs this skill contributes. component must match a key in
apps/web/src/components/BottomPanel.tsx::BOTTOM_PANEL_COMPONENTS.
output_tabs:
- id: pattern_analysis label: Pattern Analysis component: PatternContent
- id: pine_script label: Pine Script component: PineScriptPanel
Store slots this skill writes to via tool_calls (documentation only).
store_slots:
- patternMatches
- currentScript
Hints for the chat input when this skill is the only one selected.
input_hints: placeholder: "Describe a pattern to detect..." supports_fingerprint: true
Pattern Skill
Purpose
Turn a trader's pattern idea — either written in natural language or drawn directly on the chart — into a runnable JavaScript detection script that scans the active OHLC dataset and returns match regions. Vibe Trade loads the script into the code editor, runs it against the data, and surfaces results in the Pattern Analysis bottom-panel tab.
This skill is the go-to for any "find me X in the price history" question.
When to use this skill
Vibe Trade should dispatch to the Pattern Skill when the user:
- Describes a known technical pattern by name — "bull flag", "double bottom", "head and shoulders", "ascending triangle", "breakout", etc.
- Has just drawn a region on the chart via the pattern selector (a
serialized
SHAPE: [...]fingerprint arrives as the user's message) - Asks for a custom indicator — "RSI smoothed with a 20 EMA", "momentum oscillator with z-score normalization", etc.
- Pastes Pine Script code and asks for a JavaScript equivalent
Instructions
-
If the message is a fingerprint (contains
SHAPE:andSliding window):- First analyze the shape — what pattern does it resemble, what's the trend, the volatility, the implied direction?
- Ask the user for confirmation before generating a detection script.
- The chat router stores the fingerprint as
context.pending_fingerprintand waits for ayes/proceedbefore dispatching again.
-
If the message confirms a pending fingerprint (
context.pending_fingerprintis set and the user said yes), generate a shape-matching script:- Use Pearson correlation with threshold
0.50— NOT 0.85+. Strict thresholds silently produce zero matches, which looks like the skill is broken. - Fall back to returning the top 5 candidates regardless of threshold.
- Emit
script_editor.loadwith the generated JS. - Emit
bottom_panel.activate_tab→pattern_analysis.
- Use Pearson correlation with threshold
-
If the message is a named pattern ("bull flag", "double bottom"):
- Generate a detection script using price-structure rules, not shape correlation.
- Use forgiving thresholds (3–5% tolerance, not 1%).
- Emit the same two tool_calls as above.
-
If the message is an indicator request ("custom RSI...", "ATR-based stop"):
- Generate an indicator script that returns an array of values (or null for insufficient data).
- Wrap the result as
script_type: "indicator"so the frontend registers it in the Resources dropdown.
-
If the user already has a script loaded and asks for a modification (edit mode —
context.pattern_scriptis non-empty):- Return the modified script in full.
- Do NOT switch the view to Code — the user is iterating and wants the chat feedback inline.
Inputs
| Key | Type | Meaning |
|---|---|---|
message | string | Natural-language description or SHAPE fingerprint |
context.pending_fingerprint | string | Previously-analyzed fingerprint awaiting confirmation |
context.pattern_script | string | Existing script — triggers edit-mode |
context.dataset_id | string | Active dataset id (used when running the script) |
Outputs
Returns a SkillResponse with:
reply— short plain-language explanation of the scriptscript— the generated JavaScript sourcescript_type—"pattern"/"indicator"/"pine_convert"data.parameters— parameter hints extracted from the scriptdata.indicators_used— list of indicator helpers referenceddata.default_params/data.indicator_name— indicator mode onlytool_calls— see below
Tools used
This skill may emit any of the following tool_calls:
| Tool | When | Payload |
|---|---|---|
chart.pattern_selector | User asks to "mark a pattern" or similar | true to open, false to close |
chart.highlight_matches | After a successful run with matches | PatternMatch[] |
chart.draw_markers | To annotate specific bars | Marker[] |
chart.focus_range | To zoom the chart to a match region | {startTime, endTime} |
script_editor.load | Always, when a script is generated | The JS source string |
script_editor.run | When the user asks "run it now" | — |
bottom_panel.activate_tab | After generating a script | "pattern_analysis" |
bottom_panel.set_data | To push results into a tab's store slot | {target, data} |
notify.toast | Non-blocking status ("Found 7 matches") | {level, message} |
Examples
Natural-language input
"Find bull flags after a 5% rally."
→ Returns a script that scans for a strong uptrend followed by a consolidation in a downward-sloping channel, with 3% tolerance on the flag bounds. Script loads into the editor; bottom panel switches to Pattern Analysis.
Indicator input
"Custom RSI smoothed with a 20-period EMA."
→ Returns an indicator function with default_params = {rsi_period: 14, ema_period: 20}. The frontend registers it in Resources and enables it on
the chart.
Fingerprint input (from chart.pattern_selector)
Find this 285-bar pattern (scale-free):SHAPE: [0.02, 0.25, 0.67, ...]Sliding window: 285 bars
→ First pass: analyze the shape, ask for confirmation. → On confirmation: generate a correlation-based detector with threshold 0.50 and fallback-to-top-5 so the user always has something to look at.
Underlying implementation
This skill is wired through core/agents/processors.py::_pattern_processor,
which calls core/agents/pattern_agent.py::PatternAgent.generate. The
agent owns PATTERN_SYSTEM_PROMPT, INDICATOR_SYSTEM_PROMPT, and
PINE_CONVERT_PROMPT.