This skill helps you produce code that runs inside the FX Blue MyTrader platform. Four artifact types are in scope:
| Type | Runs as | Has UI? | Framework access? | Use when |
|---|---|---|---|---|
| Script | Web worker | No | Yes | Background automation — scanners, alerts, batch order management, mail handlers |
| Widget | Sandboxed iframe | Yes (HTML/CSS/JS) | Yes | Custom panels, dashboards, deal-ticket-style UIs |
| UDI | Web worker | Plots/draws on a chart | No (by default) | Indicators — moving averages, oscillators, drawings, event markers |
| UDIX | Web worker | Plots/draws on a chart | Yes | An indicator that also needs to place trades, read account state, or react to orders |
Every task starts with one question: which of these four is the user actually asking for? Get this wrong and you'll write the wrong skeleton. If the user is ambiguous, ask before fetching docs or writing code.
Common signals:
If the user asks for an algo, trading algorithm, auto-trader, EA, or expert advisor, they are not naming a fifth artifact type — a MyTrader algo can be a widget, a script, or a UDIX. The official comparison lives in section §1 of the scripting docs (fetch it for any algo request).
Default to widget for algo requests. Reasons: algos almost always benefit from UI for parameter tuning, live status, manual override / pause, and a visible kill switch — and widgets are the only artifact with a real UI surface. A widget also stays loaded as long as the user has it open, making it a natural home for a long-running strategy.
Override the default when the request actually fits another type better:
When the request is ambiguous, ask. A reasonable clarifying question: "Should this run as a widget you can see (with UI for parameters and a stop button), or as a background script with no UI? Or is it tied to a specific chart, in which case a UDIX makes sense?"
Your training data on MyTrader, if any, is stale and almost certainly wrong on specifics. The platform's API has many conventions that look generic but aren't (date encoding, indexing order, web-worker constraints, plot-buffer counts per plot type, the exact shape of data.parameters, the mandatory class name MyIndicator, the difference between this.createDrawing in modern UDIs and UDI.createDrawing in legacy UDIs). Do not improvise from memory. Fetch the relevant documentation before writing or revising any non-trivial code.
This applies even when the user pastes existing code that "looks right" — verify the API calls against current docs before suggesting changes.
The two doc roots are:
Framework.* and FXB.* namespaces, the FXB.ta technical-analysis library, and chart/order/account APIs): https://api.fxblue.com/mytrader/scripting/markdownMyIndicator class, onInit/onCalculate, plots, drawings on chart, event markers, bar highlights, deal ticket from indicators): https://api.fxblue.com/mytrader/udi/markdownThe UDIX is a hybrid — it's a UDI that opts into framework access — so UDIX work usually needs both doc roots.
https://api.fxblue.com/mytrader/scripting/markdown is a Markdown contents page. It lists every section of the reference as a link to that section's own .md file, served from sub-URLs beneath the same root and served over HTTPS. Each section file is small and self-contained, and sections cross-link to each other, so once you are inside the docs you can follow links rather than returning to the contents page.
Identify the artifact type first, then follow the contents page's routing for that type. For widgets that means reading 1.1.3 Guidance for LLMs building MyTrader widgets in full and then following its links. For scripts it means 1.1.4 Canonical script skeleton and 1.6.1 Script lifecycle.
Do not read the widget guidance for a script task. The widget bootstrap — new FXB.Framework(), then deferring all initialisation until OnLoad fires — applies to widgets and to nothing else. Carried into a script it produces code that loads cleanly and then sits there doing nothing, with no error to diagnose.
Do not hardcode or hand-construct per-section URLs. The filenames are sequence-numbered and slugified — of the form <NNN>-<section-number>-<slugified-title>.md (for example 021-1.6.1-script-lifecycle.md, or 314-relative-strength-index-fxb-ta-rsi.md for a technical-analysis entry). The sequence numbers and slugs shift as sections are added, renamed, or reordered, so a URL you assemble from a template will often 404 even when the section number is right. Always copy the exact URL from the contents page, or follow a link from a section you have already fetched.
Workflow:
https://api.fxblue.com/mytrader/scripting/markdown. It lists every section with its current URL.Quick lookup map for common tasks (find these by section number on the contents page — numbering may shift):
11.1.3 (LLM guidance — read every time), 1.1.1 (canonical skeleton), 1.1.2 (full example)1.1.4 (canonical skeleton), 1.6.1 (lifecycle)1.2.*1.3.1, browser modals 1.3.2, widget sandboxing 1.3.31.4, 1.5, 1.5.11.6.1 (script), 1.6.2 (UDIX), 1.6.3 (widget), 1.6.3.1 (permanent widgets)1.7.*1.9.*1.112.4.*, 2.5.*2.6–2.102.11.*2.13.*, 2.143.1, 3.2.*, 5.1.*3.3.*3.3.2.3, 3.3.2.4, 3.3.2.53.5.*3.6.*3.7.*3.8.*3.9.*3.103.11.*; value formatting: 3.12.*3.14.*; economic calendar: 3.15; mail system: 3.16.*; logging: 3.174.*FXB.ta library: 5.2.* (full alphabetical index of calculations at 5.2.8)6.*FXB.utils helpers: 7.*8.*9.*https://api.fxblue.com/mytrader/udi/markdown is a Markdown contents page, the same shape as the scripting reference. It is no longer a single page: fetching the root gives you the index, not the content. It lists each section of the UDI documentation as a link to that section's own .md file, served from sub-URLs beneath the same root over HTTPS. Sections are small, self-contained, and cross-link to each other, and each ends with "Next:" links to the sections that usually follow it — so once you are inside the docs you can follow links rather than returning to the contents page.
Two blocks on the contents page are worth reading on every UDI/UDIX task, before any section: "For LLMs Building UDIs", a short list of the mistakes that models reliably make against this API, and "Quick Lookups", a table mapping a task ("drawing lines on the chart", "responding to user clicks on markers", "converting between UTC and chart time") to the section that covers it. Route through the table rather than guessing which section holds what.
Do not hardcode or hand-construct per-section URLs. As with the scripting reference, the filenames are sequence-numbered and slugified, and they shift as sections are added, renamed, or reordered. Copy the exact URL from the contents page, or follow a cross-link from a section you have already fetched.
Workflow:
https://api.fxblue.com/mytrader/udi/markdown.MyIndicator class section earn their place on almost any UDI task; the rest is task-dependent.Rough map of what lives where — by title rather than by number, since numbering may shift:
MyIndicator class structure, the mandatory class name, required vs optional methods, what the base class provides → class sectiononInit() — plots and plot types, settings fields, axis customisation, context data → initialisationonCalculate() — input data, currentBarUpdateOnly / singleNewBar, output buffers, the FXB.ta library, FXB.CandleStore → calculating dataonContextChange() / onParameterChange() → chart changesUDI. namespace format and migration → legacy sectionThe example files are listed in the examples reference section, which the contents page links to. These examples are the fastest way to understand a specific pattern. Fetch the example whose pattern matches:
https://api.fxblue.com/mytrader/udi/examples/<NN>-udi-<name>.js
Pattern → example mapping:
01 Basic SMA, full recalc every tick — minimal indicator skeleton02 Efficient SMA — currentBarUpdateOnly / singleNewBar handling (the standard pattern)03 Hull MA via FXB.ta.HullMA — LoadData / UpdateCurrent / GetCurrentValue pattern04 MACD — multi-plot, maType settings field, FXB.ta composition05–08 Histograms (sub-panel, multi-colour, floatingHistogram)09 Channel + line plot10 Candle plot (4 buffers), select settings field11 Fractals via point plot — markerOffset, lineStyle:"icon-nnnn" for FontAwesome12–15 Drawings — create, move, change properties, lifecycle cleanup16 Event markers17 Bar highlights — handles the "current bar crosses threshold" lifecycle18 HTML in chart — createHTML, sendHTMLMessage, onHTMLMessage, createToast19 MTF intra-period EMA done correctly (no time-travelling)20 Higher-timeframe candles via FXB.CandleStore.Aggregate21 ATR + event-markers capstoneWhen a task fits one of these patterns, fetch the example and the relevant UDI doc section, then adapt rather than write from blank.
These are starting points only. Always verify against freshly-fetched docs before writing — they may have evolved since this skill was written.
class MyIndicator extends UserDefinedIndicator {
onInit(data) {
return {
caption: "My indicator",
isOverlay: true,
plots: [
{ type: "line", caption: "value", color: "blue", lineWidth: 2 }
],
settingsFields: [
{ id: "Source" }, // special — gives valueData instead of barData
{ id: "period", caption: "Period", type: "int", defaultValue: 14, min: 2 }
]
// For UDIX: add subscribeMetrics: true, subscribeOrders: true if needed
};
}
onCalculate(data, output) {
const period = data.parameters.period;
if (data.currentBarUpdateOnly) {
// Only the live bar changed — recompute just output.values[*][0]
} else if (data.singleNewBar) {
// One new bar appended — shift work, write output.values[*][0]
} else {
// Full recalc — write all of output.values[*]
}
}
// Optional: clean up drawings/markers when chart context changes
onContextChange(data) { /* removeAllDrawings() etc. */ }
onParameterChange(data) { /* same — drawings don't auto-reset */ }
}
Hard requirements to verify against the docs:
MyIndicator. To use a different internal name, alias it: class MySMA extends UserDefinedIndicator { ... } class MyIndicator extends MySMA {}output.values array length must match (e.g., channel consumes 2 buffers, candles consumes 4)data.valueData (1-D); without Source, input is data.barData.{open,high,low,close,volume,date}output.values is indexed newest-first ([0] is the current bar), same as input arraysonInit() — defer to first onCalculate()Scripts do not bootstrap the framework. Framework already exists at line one, there is no OnLoad, and the script runs until Framework.EndScript(). Never carry the widget pattern across.
// MyTrader Script — paste into: the script editor
// No `new FXB.Framework()` and no OnLoad — both are widget-only.
// Framework calls are safe from the first line:
Framework.Instruments.forEach(function(instrumentId, instrument) {
// Dictionary iteration passes (key, object), not just (object).
});
Framework.OnPriceChange = function(quote) {
// quote.instrumentId, quote.bid, quote.ask ...
};
Framework.OnMessage = function(Msg) {
if (!Msg) return;
// Separate `if (Msg.is(...))` blocks — never switch, never else-if.
};
// EndScript() goes wherever the work actually finishes. For anything
// asynchronous that is inside a callback, not at the top level —
// terminating early destroys any dialog still waiting for a response.
Framework.Ask("Close all open positions?", function(Msg) {
// ... act on the response ...
Framework.EndScript();
});
Fetch 1.1.4 and 1.6.1 to confirm the details before writing anything non-trivial.
Widgets are HTML/CSS/JS in a sandboxed iframe with framework access via a Framework object. Always read section 1.1.3 ("Guidance for LLMs building MyTrader widgets") in full before writing one, then follow its links — including 1.1.1 (canonical widget skeleton) and the 1.2.* sections on linking the framework's JS/CSS, creating the Framework instance, and waiting for it to become available. None of this is obvious and all of it is easy to get wrong.
A UDIX is a UDI with framework access. The UDI side is the same as above. To call into the framework from inside the indicator class, use the Framework object — which, as with a script, is provided automatically and needs no constructor. UDIX adds the ability to call Framework.SendOrder, read Framework.Account, etc. Check data.context.isUDIX to confirm framework access is actually granted before relying on it.
Everything in this section applies only when you are Claude, running in Claude's own chat interface (claude.ai or the Claude app), delivering code as an artifact. This document is also fetched by an AI feature embedded in the MyTrader platform itself, via the Anthropic API. In that context none of this section applies: the user already has the platform open in front of them, so sending them to an external preview chart is redundant at best and confusing at worst, and the artifact-and-Copy-button model the section is built around does not exist there.
Before offering a preview, all of these must hold:
If any of these is uncertain, skip the preview. Omitting it costs the user one convenience they will never know they missed. Offering it in the wrong place sends a user who is already in the platform out to a redundant external chart, which is exactly the kind of confusion the output-format rules exist to prevent.
A UDI or UDIX can be run live on a chart in the browser before the user pastes it into MyTrader, by embedding the source in the fragment of a hosted URL. It answers "does this actually work?" in one click, without the user going through the platform's load steps at all.
Offer it in words first. Do not generate the link unless the user asks for it. The payload is a long, high-entropy string, and emitting it takes upwards of a minute of visible, character-by-character output. That is a real cost to impose on someone who was not going to click it — and most users, once they have loaded a few of these, will not. A one-line offer costs nothing and lets them choose.
Widgets are not previewed. A widget preview loads a real framework session, but one backed by a context with no trading rights or a throwaway demo account — so a widget that displays open trades, pending orders, balance or history renders an empty box. That is most widgets. The preview would be showing the user a correct widget looking broken, which is worse than no preview: they cannot read the code to tell the difference, and the natural conclusion is that you got it wrong. Do not offer one, and do not construct a widget preview URL.
Scripts have no visual surface and cannot be previewed at all.
So: previews are for indicators, and only indicators.
https://mytrader.fxbluelabs.com/iframe-fxblue-llm/widget?type=chart&instrumentId=<INSTRUMENT>&timeframe=<SECONDS>&inline-udi=yes#<PAYLOAD>
The fragment is the payload and nothing else — no parameter name, no prefix. The path says widget because it is the platform's general embed endpoint; inline-udi=yes is what makes it a chart carrying your indicator. Note it is /iframe-fxblue-llm/, not /iframe-fxblue/ — the latter will not accept an inline payload.
The fragment is never transmitted to the server, so there is no URL-length limit imposed by the host, no server log holding the user's code, and nothing stored anywhere. Say so if the user asks; traders are often protective of strategy code.
instrumentId — percent-encode the slash: GBP%2FUSD. Raw slashes work when typed into a browser address bar but not reliably through every link-handling path.
timeframe — in seconds: M1 60, M5 300, M15 900, M30 1800, H1 3600, H4 14400, D1 86400, W1 604800.
Set both to match what the indicator was written for. An MTF or ATR-based indicator previewed on an arbitrary default period looks broken when it is fine. Both have safety mechanisms on the platform side, so an unrecognised value degrades rather than failing hard — don't over-think an unusual instrument name, just try it.
Three steps in order:
//, strip leading indentation, and drop blank lines. Nothing else.wbits=-15; pako.inflateRaw on the far side).- and _, padding stripped. Standard base64 is not safe: + survives a fragment in principle but not every chat client and URL-rewriter in between, and +→space corrupts silently.The minification rules are narrow on purpose, and the boundaries matter more than the savings:
// comments. A trailing comment cannot be stripped safely without parsing, because a // inside a string literal — a URL, most obviously — would take the rest of the line with it. A line that begins with // is never mid-expression, so the whole-line rule sidesteps the hazard without needing a string-aware pass./* */ alone. It can span lines and appear inside strings; removing it needs a parser.Comments are where the savings are. They are high-entropy prose that compresses against nothing else in the file, and the guidance in "Output format" tells you to comment generated code heavily — so a generated indicator is unusually comment-dense. Stripping whole-line comments alone takes roughly 30% off a typical payload. The user still receives the fully-commented file in the artifact; only the preview payload is minified. If the preview throws a runtime error its line numbers won't match the artifact — acceptable, since the preview answers "does it work" and real debugging happens against the real file.
Measured examples:
| source | payload | URL | |
|---|---|---|---|
| indicator, minified + deflate | 2,289 | 499 | 599 |
Indicator payloads are small, so the cap below will rarely bind. It is a backstop for an unusually large indicator, not a routine check you should expect to fail.
Cap: if the payload exceeds 5,000 characters, do not offer a preview at all. Above that the emission takes long enough that it stops being a convenience, and a user watching two minutes of gibberish scroll past has been given a worse experience than no preview at all. The platform imposes no such limit — payloads of 40,000 characters have been tested end to end and render correctly — so this ceiling is about the cost of emitting the link, not about whether it would work. Check the length after encoding and before offering. When you are over the cap, simply say nothing about previews: mentioning one the user cannot have is worse than silence.
You should only be here because the user asked for a preview. If they have not, stop: make the offer and wait.
Print the complete URL from your encoding step and copy it verbatim into your reply. Never hand-assemble a payload, and never emit one your tooling has not printed in full.
A base64 payload is high-entropy and unverifiable by eye, which makes it exactly the kind of string a language model will produce plausible-looking nonsense for. Printing only the payload's length is not enough — you must have the characters themselves in front of you. Verify the round-trip (decode your own output and compare bytes to the source) before handing the link over. Writing the link to a file and presenting that is not an option — the same framing restrictions apply — so the URL has to be emitted into your reply, and it has to be the one your tooling produced.
If a preview fails, the first diagnostic is length and alphabet, not the code:
const s = location.hash.slice(1);
console.log('len', s.length, 'mod4', s.length % 4);
console.log('bad chars', [...new Set(s.replace(/[A-Za-z0-9\-_]/g, ''))]);
A length that disagrees with what you emitted means the payload was truncated or fabricated. mod4 === 1 is impossible for valid base64 and indicates truncation. Non-empty bad chars means the wrong alphabet or percent-encoding.
Give it as a clickable Markdown link that opens in a new tab. This is the only mechanism that works. The alternatives — embedding the preview in an artifact, submitting a form, opening a window and messaging it, or substituting your own copy button — have all been tested and are unavailable. Do not spend effort rediscovering them, and in particular never replace the client's own Copy button with one of your own: losing the ability to get the code out is a total failure, and it fails silently.
Place the offer, and later the link, after the paste instruction, never before it. The Copy button and the paste step are the interaction that must succeed; the preview is a convenience that must not compete with them. A user who clicks a preview, sees their indicator drawing, and concludes they are finished has been actively harmed by it.
The offer is one line, and it states the wait, so that a user who says yes is not surprised by it:
Want a preview link to check it works on a chart before you load it? It takes me about a minute to generate.
Naming the delay is not an apology for it — it is what lets someone decline cheaply, and what stops the wait feeling like a fault when they accept. Do not use bold text, headings, emoji, or horizontal rules for the offer; it should read as a closing aside.
When the user accepts, set the link off as a blockquote, so it reads as a margin note rather than part of the instructions:
> **Preview** — [see it on a chart](URL) before loading it. Doesn't replace pasting it into the platform.
Offer once per session, on first delivery. After that, offer again only if the user took it up before, or asks. Someone who ignored the first offer has answered; repeating it turns a convenience into nagging, and the whole point of offering rather than generating is that declining should be cheap and final.
A generated link goes stale. It carries a snapshot of the code, not a reference to it, so an earlier link silently previews the earlier version. If the user has taken up previews and you then revise the code substantively, either regenerate the link or say plainly that the existing one is now out of date. A fix that "didn't work" because they clicked a stale link is the easiest way to waste someone's time.
UDIXes preview with framework access enabled. The preview cannot touch the user's money: preview contexts either have no trading rights or are backed by a disposable dummy demo account. Reassure the user of this if they ask, and never imply the preview is a live-trading surface.
For indicators it is highly representative. Bar data is bar data: what plots in the preview will plot in the platform.
For a UDIX, the indicator side previews faithfully, but anything it reads from the account does not: the preview context has no trading rights or a throwaway demo account, so positions, orders and balances will be empty or dummy. If the UDIX draws signals from bar data it will look right; if it colours markers by open position, it will not. Say so when it applies, rather than caveating every link.
The preview does not reflect platform settings, saved chart state, or the user's own account. A successful preview is evidence the code loads and runs — not that it behaves correctly against live account state.
Both doc roots carry a dedicated "Common pitfalls" section: the UDI doc's sits inside its introduction section (currently §1.8 of that file), and the scripting reference's is currently §1.11. Fetch the one matching what you're building — both, for a UDIX — before writing code. Between them they cover the substantive traps (MTF time-travel, drawing/marker/highlight lifecycle, date encoding in chart time vs UTC, the currentBarUpdateOnly / singleNewBar incremental-update pattern, select field string-coercion, output.values fixed-length buffers, web-worker constraints, and the modern-vs-legacy format split). Don't try to remember these from this skill — fetch the canonical version, since wording, scope, and section numbering may shift.
Note that the scripting reference's pitfalls list is written for all four artifact types at once, and several entries are widget-specific. Read the qualifier on each one rather than the headline: the OnLoad rules in particular invert between widgets and everything else.
Three further notes apply specifically to generated code:
If you don't see an API in the freshly-fetched docs, it doesn't exist. The framework is large enough that "this seems like it should be how it works" is rarely a safe heuristic. Fetch one more section before guessing. This applies especially to method names that sound conventional (e.g., removeIndicator, setColor, getCurrentBar, onTick) but may not match what's actually exposed. If you genuinely can't find what you need, say so and ask the user — don't fabricate.
new FXB.Framework() and OnLoad belong to widgets and to nothing else. If you are writing a script or a UDIX and find yourself constructing the framework, or deferring work into an OnLoad handler, you have carried a pattern across from the widget documentation. Scripts and UDIXes receive a Framework object ready to use before their first line runs.
This failure is silent. The code loads, no error appears, and nothing ever happens — so it will not surface as an exception in testing, and the user may report it as "the script does nothing" rather than as a crash. Check for it explicitly before delivering any script or UDIX.
Modern: class MyIndicator extends UserDefinedIndicator { ... this.createDrawing(...) ... }. Legacy: UDI.onInit = function(data) { ... UDI.createDrawing(...) ... }. Pick one — they cannot be combined in a single file. Default to modern. Only use legacy if the user explicitly says they're on an older platform version (the giveaway is whether the Add UDI dialog has separate Code and URL tabs — newer versions do). Converting between the two is mechanical: find-and-replace UDI. ↔ this. after moving the handlers in or out of the class body.
When delivering code:
State the artifact type explicitly at the top of your reply ("This is a UDIX — load it with framework access via the Add UDI dialog and check 'Provide framework access'."). This statement goes in the chat reply, not inside the artifact.
Always deliver the complete file as an artifact — the panel that opens in the sidebar — and never as an inline fenced code block. The sidebar artifact carries a large, permanently-visible Copy button; inline code only has a small copy icon that the user has to scroll back up to hunt for. MyTrader users are mostly non-technical traders rather than developers, so an obvious one-click copy matters more than inline readability. This applies to all four types — scripts, widgets, UDIs, and UDIXes. There is no size below which inline becomes acceptable: this explicitly includes one-line fixes, follow-up edits and debug corrections, and short illustrative snippets. If it is code the user might paste into MyTrader, it goes in an artifact — do not carve out "this one is too small to bother" exceptions.
Create it as a code artifact, not a live preview — and do this mechanically, not by intent alone. Choose the artifact type deliberately: deliver the file as a non-rendering code/text artifact (the kind that shows source text with a Copy button), not a previewing one. For a widget specifically, use a plain code/text artifact even though the contents are HTML, and never an HTML artifact that the client will try to render — a widget has no Framework object and no surrounding platform in the sidebar, so any render attempt only produces errors. The artifact pane is a copy-and-paste surface, not a run surface — the code runs only once pasted into MyTrader. Tell the user plainly that the widget will not display in the sidebar and that this is expected. There is no preview link for widgets either; the platform is the only place a widget runs.
If the surface renders the widget anyway, do not leave it unexplained. Some clients force a preview on HTML regardless of how the artifact is created, so a render may happen despite the rule above. When it does, say so explicitly: tell the user the broken/error-filled preview is expected, that it is not a bug in their widget, and that they should ignore it and copy the source from the panel. Never let an errored render stand on its own — an unexplained error screen is exactly the confusion this whole rule exists to prevent.
Keep the artifact pure code. Put only the file's contents in the artifact (inline comments are fine and encouraged — see point 9). All surrounding prose — the artifact-type statement, where-to-paste instructions, docs consulted, and manual-setup flags — goes in the chat reply, so that "Copy" returns nothing but paste-ready code.
Title the artifact with the type and a short descriptive name (e.g. "Pin-bar scanner — Script", "MACD — UDI", "RSI divergence — UDIX") so it is obvious what it is and where it goes.
Tell the user where to paste it: Add UDI → Code tab for UDIs/UDIXes; the script editor for scripts; the widget editor for widgets.
For UDIs, the entry-point class must be named MyIndicator. If you want a more descriptive internal name, use the synonym pattern: class MySMA extends UserDefinedIndicator { ... } class MyIndicator extends MySMA {} — and make the alias the last line of the file, so its presence is checkable at a glance. Omitting it fails silently: the file loads, no error appears, and the chart simply stays empty. Like the new FXB.Framework() mistake above, the user will report this as "nothing happens" rather than as a crash, and will reasonably suspect the platform rather than the code. Verify the alias is there before delivering any UDI or UDIX.
Inline-comment any non-obvious decisions — especially around incremental updates (currentBarUpdateOnly / singleNewBar), drawing lifecycle, MTF, and date conversion. Open the file with a short header comment naming the artifact type and where it goes (e.g. MyTrader UDI — paste into: Add UDI → Code tab). This travels with the copied text, so the instruction is in front of the user at the moment they paste.
After presenting the artifact, briefly list which doc sections / example files you consulted so the user can verify if anything looks off.
In Claude's chat interface only — see the precondition at the top of "Previewing code before it's loaded", and skip this entirely if you are running inside the MyTrader platform or any other application. For UDIs and UDIXes only — never for widgets or scripts — offer a live preview link in one sentence, after the paste instruction from point 7, and do not generate it unless the user asks, because emitting the payload takes about a minute of visible output. Offer once per session; skip the offer entirely if the encoded payload would exceed 5,000 characters.
Flag any settings the user must configure manually after pasting (e.g., "this widget needs to be added as a permanent widget, not a one-shot dialog" or "load this with framework access").
When reviewing or debugging existing code:
class MyIndicator extends UserDefinedIndicator, UDI.onInit, top-level async script, or HTML+Framework usage).new FXB.Framework() or an OnLoad handler. Both are widget-only, and both explain a component that loads without error and then does nothing.