Skip to main content
ATK Pine Script®

Best Practices and Anti-Patterns

Recommended patterns and common mistakes to avoid when writing ATK PyneScript V6 scripts.

Best Practices#

Do this#

  • Compute everything in the appropriate frame builder.
  • Use visual_* columns for row-aligned visuals.
  • Use frame.attrs only for static object config.
  • Use stable key values for visuals and inputs.
  • Prefer build_mapped_trade_frame for strategies.
  • Use import_library(...) inside raw .py scripts and reserve quoted imports for editor-preprocessed source.
  • Quote examples from source/example_user_scripts so users can paste and run them immediately.

Do not do this#

  • Do not compute TA inside build_visuals.
  • Do not compute strategy logic inside build_trade_frame.
  • Do not store dynamic, slice-sensitive payloads entirely inside frame.attrs.
  • Do not teach users outdated examples that hide stage boundaries.
  • Do not fix runtime parity problems only inside user examples when the correct fix belongs upstream.

Stage Ownership Summary#

StageWhat belongs hereWhat must not happen here
build_indicator_frameAll indicator series computation, source resolution, warmup handling, row-oriented visual_* prep, static attrs config.Final drawing calls through ctx.*.
build_signal_frameSignal logic, filter logic, canonical trade-frame execution fields, strategy visuals prep.Order schema normalization beyond mapping-only helpers.
build_trade_frameMapping-only normalization, usually build_mapped_trade_frame(...).ta.*, request.*, rolling windows, dataframe grouping, signal recomputation.
build_visualsRender-only mapping into ctx.* or ctx.atk.*.Mutating the frame, computing TA, storing stale full-frame dynamic payloads in frame.attrs.

Decision Guide#

If you need to...Put it hereReason
Choose between open, close, hl2, or a user-selected source columnbuild_indicator_frame or build_signal_frameSource selection is part of computation, not rendering.
Compute EMA, ATR, BBands, MACD, or MTF trend filtersbuild_indicator_frame or build_signal_frameAll TA and request work belongs in compute stages.
Emit entry_price, sl, tpbuild_signal_frameStrategies should fully prepare execution fields before trade mapping.
Convert canonical trade-frame columns into the runtime's normalized schemabuild_trade_frameThis stage exists for normalization, not for new trading logic.
Create a dashboard table, zone box, or object bundle from prepared payloadbuild_visualsIt is pure rendering of already-prepared data.
Store a static style bundle such as table colors, widths, headers, or label templatesframe.attrsStatic config is safe here because it does not depend on the current slice length.
Store last-row x/y anchors, projected tails, or slice-dependent indicesDo not pre-store them wholesale in frame.attrsThose values can go stale when the runtime passes only a slice into build_visuals.

If you use frame.attrs for object-like visuals, store only static config there and derive dynamic x, y, tail, or slice-dependent values from the actual frame passed into build_visuals().