MyTrader development skill — hosted body

This is the canonical body of the mytrader-development skill. The skill artifact uploaded to Claude products is a thin bootstrap that fetches this content every time the skill triggers, so updating it updates the skill for all users immediately.

This Markdown file is the editable source; it is served to Claude as HTML at https://www.fxblue.com/mytrader/mytrader-development.html (HTML so search engines index it). It deliberately has no YAML frontmatter — the frontmatter (skill name and triggering description) lives in the bootstrap shim, since metadata must be present in the uploaded artifact for skill discovery.


Writing MyTrader scripts, widgets, and indicators

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:

Special case: trading algos

If the user asks for an algo, trading algorithm, auto-trader, EA, or expert advisor, they are not naming a fourth 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?"


The non-negotiable rule: fetch the docs fresh

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:

The UDIX is a hybrid — it's a UDI that opts into framework access — so UDIX work usually needs both doc roots.


How to fetch efficiently

Scripting reference — a Markdown contents page linking to per-section Markdown files

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.

Start here for widgets: the contents page itself directs LLMs to read 1.1.3 Guidance for LLMs building MyTrader widgets in full before writing any code, and then to follow that section's links onward. Do that for any widget task — it is the entry point the docs are designed around, and it points at the sections that matter for the specific job.

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 020-1.6.1-script-lifecycle.md, or 313-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:

  1. Fetch the contents page once: https://api.fxblue.com/mytrader/scripting/markdown. It lists every section with its current URL.
  2. For widget work, fetch 1.1.3 next and let it steer you.
  3. Otherwise pick the 2–8 sections that match the task. Resist the urge to fetch the whole reference.
  4. Fetch each picked section using the URL exactly as the contents page (or a cross-link) gives it.

Quick lookup map for common tasks (find these by section number on the contents page — numbering may shift):

UDI reference — one page, plus example files

The UDI reference is a single page. Fetch it once when starting any UDI/UDIX task.

It also lists 21 numbered example files in section 1.2. These examples are the fastest way to understand a specific pattern. Fetch the example whose pattern matches:

https://www.fxblue.com/mytrader/udi/examples/<NN>-udi-<name>.js

Pattern → example mapping:

When a task fits one of these patterns, fetch the example and the relevant UDI doc section, then adapt rather than write from blank.


Skeletons

These are starting points only. Always verify against freshly-fetched docs before writing — they may have evolved since this skill was written.

Modern UDI / UDIX

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:

Script (framework-driven)

The script lifecycle has its own conventions — fetch section 1.6.1 before writing. The general shape involves async/await against Framework.* calls, message handlers (OnPriceChange, OnOrderX, etc.), and explicit cleanup. Don't guess the entry point.

Widget

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.

UDIX-specific notes

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 once it's available. 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.


Common pitfalls

Both doc roots carry a dedicated "Common pitfalls" section: the UDI doc's is currently §1.9, 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.

Two further notes are AI-specific and don't belong in user-facing docs:

Don't invent functions or properties

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.

Don't mix modern and legacy UDI formats in the same file

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.


Output format

When delivering code:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. Tell the user where to paste it: Add UDI → Code tab for UDIs/UDIXes; the script editor for scripts; the widget editor for widgets.

  8. 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 {}.

  9. Inline-comment any non-obvious decisions — especially around incremental updates (currentBarUpdateOnly / singleNewBar), drawing lifecycle, MTF, and date conversion.

  10. After presenting the artifact, briefly list which doc sections / example files you consulted so the user can verify if anything looks off.

  11. 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: