@forgecharts/sdk 1.3.8 → 1.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/tools.ts","../../src/server/knowledge.ts","../../src/server/systemPrompt.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Agent Tool Definitions for Anthropic API\n *\n * This module exports all tool schemas that the agent can use. Tools are organized\n * by category: Chart Navigation, Market Data, Indicators, Drawings, ForgeScript,\n * Layout, Watchlist, and Trading (read-only).\n */\n\ninterface ToolInput {\n type: 'object';\n properties: Record<string, unknown>;\n required: string[];\n}\n\ninterface Tool {\n name: string;\n description: string;\n input_schema: ToolInput;\n}\n\n/**\n * Gets the complete array of agent tool definitions in Anthropic API format.\n * Each tool has a name, description, and input schema.\n */\nexport function getAgentTools(): Tool[] {\n return [\n // ─── Chart Navigation ──────────────────────────────────────────────\n {\n name: 'chart_get_state',\n description: 'Get the current state of the chart including symbol, timeframe, type, and visible range.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'chart_set_symbol',\n description:\n 'Change the currently displayed symbol (ticker). For futures, use continuous notation (e.g., \"CME:ES1!\") or specific contracts (e.g., \"CME:ESM2026\"). Always include the exchange prefix for futures.',\n input_schema: {\n type: 'object',\n properties: {\n symbol: {\n type: 'string',\n description: 'Symbol to display. Examples: \"AAPL\", \"BTCUSD\", \"CME:ES1!\" (continuous), \"CME:ESM2026\" (specific month)',\n },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'contract_get_info',\n description:\n 'Get futures contract information for a symbol: whether it is continuous or specific, the current front-month contract, and a list of upcoming available contracts. Call this BEFORE switching futures symbols to help the user choose between continuous and specific contracts.',\n input_schema: {\n type: 'object',\n properties: {\n symbol: {\n type: 'string',\n description: 'Futures symbol to look up (e.g., \"ES\", \"ES1!\", \"CME:ESM2026\", \"CL\"). Defaults to the current chart symbol if omitted.',\n },\n },\n required: [],\n },\n },\n {\n name: 'chart_set_timeframe',\n description: 'Change the chart timeframe (e.g., \"1m\", \"5m\", \"1h\", \"1d\").',\n input_schema: {\n type: 'object',\n properties: {\n timeframe: { type: 'string', description: 'Timeframe identifier (1m, 5m, 15m, 1h, 4h, 1d, 1w, etc.)' },\n },\n required: ['timeframe'],\n },\n },\n {\n name: 'chart_set_type',\n description: 'Change the chart type (candlestick, line, area, bar, etc.).',\n input_schema: {\n type: 'object',\n properties: {\n type: { type: 'string', description: 'Chart type (candlestick, line, area, bar, renko, etc.)' },\n },\n required: ['type'],\n },\n },\n {\n name: 'chart_scroll_to_date',\n description: 'Scroll the chart to a specific date/timestamp.',\n input_schema: {\n type: 'object',\n properties: {\n timestamp: { type: 'number', description: 'Unix timestamp (seconds) to scroll to' },\n },\n required: ['timestamp'],\n },\n },\n {\n name: 'chart_set_visible_range',\n description: 'Set the visible price range (Y-axis) on the chart.',\n input_schema: {\n type: 'object',\n properties: {\n minPrice: { type: 'number', description: 'Minimum price to display' },\n maxPrice: { type: 'number', description: 'Maximum price to display' },\n },\n required: ['minPrice', 'maxPrice'],\n },\n },\n\n // ─── Market Data ──────────────────────────────────────────────────\n {\n name: 'data_get_bars',\n description:\n 'Fetch OHLCV bars for analysis. CRITICAL: Always call this BEFORE placing drawings to find exact price levels.',\n input_schema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol to fetch bars for' },\n timeframe: { type: 'string', description: 'Timeframe (1m, 5m, 1h, 1d, etc.)' },\n limit: {\n type: 'number',\n description: 'Number of bars to fetch (default 100)',\n },\n from: {\n type: 'number',\n description: 'Unix timestamp (seconds) to start from (optional)',\n },\n to: {\n type: 'number',\n description: 'Unix timestamp (seconds) to end at (optional)',\n },\n },\n required: ['symbol', 'timeframe'],\n },\n },\n {\n name: 'data_get_realtime_quote',\n description: 'Get the current bid/ask/last price for a symbol.',\n input_schema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol to fetch quote for' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'data_get_session_ohlc',\n description: 'Get current session OHLC stats (open, high, low, last, settlement) for a symbol.',\n input_schema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol to fetch session OHLC for (optional, uses current chart symbol if not provided)' },\n },\n required: [],\n },\n },\n\n // ─── Indicators ───────────────────────────────────────────────────\n {\n name: 'indicator_list',\n description: 'List all indicators currently applied to the chart.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'indicator_add',\n description:\n 'Add a built-in technical indicator to the chart. ALWAYS prefer this over ForgeScript for standard indicators. Built-in types: \"sma\", \"ema\", \"wma\", \"rsi\", \"macd\", \"bbands\" (Bollinger Bands), \"stochastic\", \"atr\", \"obv\", \"volume\". Overlay indicators (sma, ema, wma, bbands) render on the price chart; non-overlay indicators (rsi, macd, stochastic, atr, obv, volume) get their own sub-pane. Built-in indicators include a full settings dialog (gear icon) for users to adjust parameters.',\n input_schema: {\n type: 'object',\n properties: {\n type: { type: 'string', description: 'Indicator type in lowercase: ema, sma, wma, rsi, macd, bbands, stochastic, atr, obv, volume' },\n params: {\n type: 'object',\n description: 'Indicator parameters. Examples: {\"period\": 50} for EMA/SMA, {\"period\":20,\"maType\":\"sma\",\"source\":\"close\",\"multiplier\":2,\"offset\":0} for bbands (maType: \"sma\"|\"ema\"|\"wma\"; source: \"close\"|\"open\"|\"high\"|\"low\"|\"hl2\"|\"hlc3\"|\"ohlc4\"), {\"fast\":12,\"slow\":26,\"signal\":9} for MACD',\n },\n overlay: {\n type: 'boolean',\n description: 'Whether to render on the price chart (true) or in a separate sub-pane (false). Defaults are automatic per type — only set this to override the default placement.',\n },\n visible: {\n type: 'boolean',\n description: 'Whether the indicator should be visible (default true)',\n },\n style: {\n type: 'object',\n description: 'Optional visual style overrides. Keys: line1, line2, line3 (each with color, width, lineStyle: \"solid\"|\"dashed\"|\"dotted\", visible), fill1 (color, opacity 0-1, visible). Example for bbands: {\"line1\":{\"color\":\"#ff0000\"},\"line2\":{\"color\":\"#00ff00\",\"width\":2},\"fill1\":{\"opacity\":0.15}}',\n },\n },\n required: ['type'],\n },\n },\n {\n name: 'indicator_remove',\n description: 'Remove an indicator from the chart.',\n input_schema: {\n type: 'object',\n properties: {\n indicatorId: { type: 'string', description: 'ID of the indicator to remove' },\n },\n required: ['indicatorId'],\n },\n },\n {\n name: 'indicator_update_params',\n description: 'Update parameters of an existing indicator.',\n input_schema: {\n type: 'object',\n properties: {\n indicatorId: { type: 'string', description: 'ID of the indicator' },\n params: {\n type: 'object',\n description: 'New parameters to apply',\n },\n },\n required: ['indicatorId', 'params'],\n },\n },\n {\n name: 'indicator_set_visible',\n description: 'Show or hide an indicator.',\n input_schema: {\n type: 'object',\n properties: {\n indicatorId: { type: 'string', description: 'ID of the indicator' },\n visible: { type: 'boolean', description: 'Whether to show (true) or hide (false)' },\n },\n required: ['indicatorId', 'visible'],\n },\n },\n {\n name: 'indicator_list_available',\n description: 'Return full registry of available indicator names and their parameter schemas.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'indicator_get_values',\n description: 'Return computed output series values for a running indicator.',\n input_schema: {\n type: 'object',\n properties: {\n indicatorId: { type: 'string', description: 'ID of the indicator' },\n limit: { type: 'number', description: 'Maximum number of values to return (default 100)' },\n },\n required: ['indicatorId'],\n },\n },\n\n // ─── Drawings ─────────────────────────────────────────────────────\n {\n name: 'drawing_list',\n description: 'List all drawings on the chart (trend lines, support/resistance, annotations).',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'drawing_add',\n description:\n 'Draw on the chart (trend line, horizontal line, rectangle, text annotation, fibonacci tools, etc.). Always fetch bars first with data_get_bars to find exact price levels.',\n input_schema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n description:\n 'Drawing type: \"trendline\", \"extended_line\", \"ray\", \"horizontal_ray\", \"horizontal_line\", \"vertical_line\", \"fibonacci_retracement\", \"fibonacci_extension\", \"fibonacci_fan\", \"pitchfork\", \"rectangle\", \"channel\", \"text_label\", \"arrow_up\", \"arrow_down\", \"price_label\", \"gann_fan\", \"regression_trend\"',\n },\n p1: {\n type: 'object',\n description: 'First anchor point {time: unix_seconds, price: number}',\n properties: {\n time: { type: 'number', description: 'Unix timestamp (seconds)' },\n price: { type: 'number', description: 'Price level' },\n },\n },\n p2: {\n type: 'object',\n description: 'Second anchor point (optional for single-point types) {time: unix_seconds, price: number}',\n properties: {\n time: { type: 'number', description: 'Unix timestamp (seconds)' },\n price: { type: 'number', description: 'Price level' },\n },\n },\n p3: {\n type: 'object',\n description: 'Third anchor point (for pitchfork, fibonacci_extension, channel) {time: unix_seconds, price: number}',\n properties: {\n time: { type: 'number', description: 'Unix timestamp (seconds)' },\n price: { type: 'number', description: 'Price level' },\n },\n },\n text: {\n type: 'string',\n description: 'Text content for text_label and price_label types',\n },\n style: {\n type: 'object',\n description: 'Drawing style properties',\n properties: {\n color: { type: 'string', description: 'Color in hex format (e.g., \"#FF0000\")' },\n lineWidth: { type: 'number', description: 'Line width in pixels' },\n lineStyle: { type: 'string', description: 'Line style: \"solid\", \"dashed\", or \"dotted\"' },\n fillColor: { type: 'string', description: 'Fill color in hex format (optional)' },\n fillOpacity: { type: 'number', description: 'Fill opacity from 0 to 1 (optional)' },\n showLabel: { type: 'boolean', description: 'Whether to show the label (optional)' },\n },\n },\n },\n required: ['type', 'p1'],\n },\n },\n {\n name: 'drawing_remove',\n description: 'Remove a drawing from the chart.',\n input_schema: {\n type: 'object',\n properties: {\n drawingId: { type: 'string', description: 'ID of the drawing to remove' },\n },\n required: ['drawingId'],\n },\n },\n {\n name: 'drawing_update',\n description: 'Update properties of an existing drawing (move it, change color, etc.).',\n input_schema: {\n type: 'object',\n properties: {\n drawingId: { type: 'string', description: 'ID of the drawing' },\n points: {\n type: 'array',\n description: 'New points (optional)',\n items: { type: 'object' },\n },\n color: {\n type: 'string',\n description: 'New color in hex format (optional)',\n },\n label: {\n type: 'string',\n description: 'New label/text (optional)',\n },\n },\n required: ['drawingId'],\n },\n },\n {\n name: 'drawing_clear_all',\n description: 'DESTRUCTIVE: Remove all drawings from the chart.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'drawing_list_types',\n description: 'Return all supported drawing type identifiers.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n\n // ─── ForgeScript ───────────────────────────────────────────────────\n {\n name: 'script_list',\n description: 'List all ForgeScript custom indicators saved in the workspace. Returns an array of scripts with id, name, and created_at. Use the id field when calling script_delete or script_get_source.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'script_delete',\n description: 'Delete a ForgeScript indicator permanently. Always call script_list first to get the script id, then confirm with the user before deleting.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'UUID id of the script to delete (from script_list)' },\n },\n required: ['scriptId'],\n },\n },\n {\n name: 'script_get_source',\n description: 'Get the source code of a ForgeScript indicator.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the script' },\n },\n required: ['scriptId'],\n },\n },\n {\n name: 'script_create',\n description: 'Create a new ForgeScript indicator. Always validate before compiling. IMPORTANT: Every tuneable value (periods, thresholds, multipliers) MUST use input()/input.int()/input.float() with a descriptive title. Every plot colour MUST use input.color() so the user can customise it from the settings dialog. Never hard-code magic numbers or colours.',\n input_schema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Name of the new script' },\n source: { type: 'string', description: 'ForgeScript source code. Must include input() for all configurable parameters and input.color() for all plot colours.' },\n },\n required: ['name', 'source'],\n },\n },\n {\n name: 'script_update_source',\n description: 'Update the source code of an existing ForgeScript indicator. Always validate before compiling. Ensure all tuneable values use input() and all plot colours use input.color().',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the script' },\n source: { type: 'string', description: 'New ForgeScript source code. Must include input() for all configurable parameters and input.color() for all plot colours.' },\n },\n required: ['scriptId', 'source'],\n },\n },\n {\n name: 'script_validate',\n description:\n 'Validate ForgeScript source code for syntax and semantic errors. ALWAYS call this before script_compile_attach. Fix any errors and re-validate until clean.',\n input_schema: {\n type: 'object',\n properties: {\n source: { type: 'string', description: 'ForgeScript source code to validate' },\n },\n required: ['source'],\n },\n },\n {\n name: 'script_compile_attach',\n description:\n 'DESTRUCTIVE: Compile and attach a ForgeScript indicator to the chart. Always validate with script_validate first and fix all errors.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the script to compile and attach' },\n },\n required: ['scriptId'],\n },\n },\n {\n name: 'script_detach',\n description: 'Remove a running script from the chart.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the script to detach' },\n },\n required: ['scriptId'],\n },\n },\n {\n name: 'script_get_console',\n description: 'Return last N lines of script console output.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the script' },\n limit: { type: 'number', description: 'Number of lines to return (default 50)' },\n },\n required: ['scriptId'],\n },\n },\n\n // ─── Datasets ─────────────────────────────────────────────────────\n {\n name: 'script_dataset_create',\n description: 'Create a named dataset (table) for a script. The dataset defines typed columns that the user can later import data into. The implicit first column is always \"time\" (timestamptz). Use lowercase snake_case for dataset and column names.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the parent script' },\n name: { type: 'string', description: 'Dataset name (lowercase snake_case, 1-64 chars)' },\n columns: {\n type: 'array',\n description: 'Column definitions. Types: number, integer, text, boolean, date, timestamp, percentage, price.',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Column name (lowercase snake_case)' },\n type: { type: 'string', description: 'Column type: number | integer | text | boolean | date | timestamp | percentage | price' },\n nullable: { type: 'boolean', description: 'Whether the column allows null values (default true)' },\n },\n required: ['name', 'type'],\n },\n },\n },\n required: ['scriptId', 'name', 'columns'],\n },\n },\n {\n name: 'script_dataset_list',\n description: 'List all datasets defined for a script, including their columns, row counts, and ingest status.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the script' },\n },\n required: ['scriptId'],\n },\n },\n\n // ─── Documentation ──────────────────────────────────────────────────\n {\n name: 'script_docs_write',\n description: 'Write or update the Markdown documentation for a script. Include a summary of what the indicator does, how to use it, parameter descriptions, and any relevant notes. Called AFTER script_create and script_compile_attach to document the finished indicator.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the script' },\n content: { type: 'string', description: 'Markdown documentation content. Should include: summary, description of what the indicator calculates, parameter table, usage tips, and examples.' },\n },\n required: ['scriptId', 'content'],\n },\n },\n\n // ─── Visibility & Pricing ───────────────────────────────────────────\n {\n name: 'script_set_visibility',\n description: 'Set the visibility and pricing of a script. Use \"private\" for personal use, \"public\" to share freely, or \"for_sale\" to sell on the marketplace. When setting for_sale, sale_price (minimum $1.00) is required. Always ask the user which visibility they want before calling this tool.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the script' },\n visibility: { type: 'string', enum: ['private', 'public', 'for_sale'], description: 'Visibility level' },\n sale_price: { type: 'number', description: 'Price in USD (required and must be >= 1.00 when visibility is for_sale)' },\n preview_pct: { type: 'integer', description: 'Percentage of source code visible to non-purchasers (0-100, default 0). Only relevant for for_sale scripts.' },\n },\n required: ['scriptId', 'visibility'],\n },\n },\n\n // ─── Backtesting ──────────────────────────────────────────────────\n {\n name: 'backtest_run',\n description: 'Execute a ForgeScript strategy against OHLCV bars. Returns performance metrics and trade log.',\n input_schema: {\n type: 'object',\n properties: {\n scriptId: { type: 'string', description: 'ID of the strategy script to backtest' },\n symbol: { type: 'string', description: 'Symbol to backtest on' },\n timeframe: { type: 'string', description: 'Timeframe (1m, 5m, 1h, 1d, etc.)' },\n from: { type: 'number', description: 'Start time as Unix timestamp (seconds)' },\n to: { type: 'number', description: 'End time as Unix timestamp (seconds)' },\n params: { type: 'object', description: 'Optional strategy parameters as key-value pairs' },\n },\n required: ['scriptId', 'symbol', 'timeframe', 'from', 'to'],\n },\n },\n {\n name: 'backtest_get_trades',\n description: 'Return individual trade log from last backtest.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'backtest_get_equity_curve',\n description: 'Return equity curve as time series from last backtest.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'backtest_plot_equity',\n description: 'Draw equity curve overlay on active chart.',\n input_schema: {\n type: 'object',\n properties: {\n pane: { type: 'string', description: 'Chart pane: \"overlay\" (on main chart) or \"separate\" (new pane, default)' },\n },\n required: [],\n },\n },\n\n // ─── Layout ───────────────────────────────────────────────────────\n {\n name: 'layout_list',\n description: 'List all saved chart layouts in the workspace.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'layout_load',\n description: 'Load a saved layout (applies saved indicators, drawings, settings).',\n input_schema: {\n type: 'object',\n properties: {\n layoutId: { type: 'string', description: 'ID of the layout to load' },\n },\n required: ['layoutId'],\n },\n },\n {\n name: 'layout_save',\n description: 'DESTRUCTIVE: Save the current chart state as a named layout.',\n input_schema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Name for the layout' },\n },\n required: ['name'],\n },\n },\n {\n name: 'layout_delete',\n description: 'DESTRUCTIVE: Delete a saved layout.',\n input_schema: {\n type: 'object',\n properties: {\n layoutId: { type: 'string', description: 'ID of the layout to delete' },\n },\n required: ['layoutId'],\n },\n },\n\n // ─── Watchlist ────────────────────────────────────────────────────\n {\n name: 'watchlist_get',\n description: 'Get the symbols in the watchlist.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'watchlist_add',\n description: 'Add a symbol to the watchlist.',\n input_schema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol to add' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'watchlist_remove',\n description: 'Remove a symbol from the watchlist.',\n input_schema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol to remove' },\n },\n required: ['symbol'],\n },\n },\n\n // ─── Trading (READ-ONLY) ──────────────────────────────────────────\n {\n name: 'trading_get_positions',\n description:\n 'Get open trading positions. READ-ONLY: cannot modify or close positions. Must place orders manually in the UI.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'trading_get_orders',\n description:\n 'Get current trading orders (pending, filled, cancelled). READ-ONLY: cannot modify, cancel, or place orders. Must do this manually in the UI.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n {\n name: 'trading_get_fills',\n description: 'Get execution fills (historical trades). READ-ONLY access only.',\n input_schema: {\n type: 'object',\n properties: {\n limit: { type: 'number', description: 'Number of recent fills to fetch (default 50)' },\n },\n required: [],\n },\n },\n {\n name: 'trading_get_account_summary',\n description: 'Get account balance, buying power, P&L, and margin info. READ-ONLY access only.',\n input_schema: {\n type: 'object',\n properties: {},\n required: [],\n },\n },\n ];\n}\n","/**\n * ForgeScript Language & Runtime Knowledge Base\n *\n * This module exports consolidated ForgeScript documentation for use in\n * Claude system prompts. Two exports:\n * - FORGESCRIPT_REFERENCE: 135-line condensed reference for quick lookup\n * - FORGESCRIPT_KNOWLEDGE: Full consolidated knowledge base for detailed instructions\n */\n\nexport const FORGESCRIPT_REFERENCE = `## ForgeScript Language Reference\n\nForgeScript is a domain-specific language for financial technical indicators.\nIt uses a bar-by-bar execution model with persistent series state.\n\n### Data Series (always available)\nopen, high, low, close, volume, time, hl2, hlc3, ohlc4, bar_index\n\n### Bar State\nbarstate.islast, barstate.isfirst, barstate.isconfirmed, barstate.isnew,\nbarstate.isrealtime (always false), barstate.ishistory (always true)\n\n### Syntax\n\nCRITICAL — Assignment vs Reassignment:\n- First assignment MUST use = (equals sign): length = input(14)\n- Reassignment of an existing variable uses := (colon-equals): length := length + 1\n- NEVER use := to declare a variable for the first time — this is a runtime error\n- var (init-once per symbol): var x = 0 (uses = for the initial declaration)\n- varip (init-once per session): varip x = 0 (uses = for the initial declaration)\n- if/else (using indented blocks)\n- for i = start to end [by step] (indented block)\n- while condition (indented block)\n- Ternary: condition ? then : else\n- Index lookback: series[n] — access n bars ago\n- Named arguments: plot(val, title=\"EMA\", color=#FF0000)\n\n### Built-in Functions\n\n#### Technical Analysis (flat or ta.* namespace)\nsma, ema, wma, rma, rsi, stdev, atr, highest, lowest, change, mom,\ncrossover, crossunder, cross, macd, bb, stoch, obv, correlation,\ndev, variance, cum, sum, valuewhen, barssince, pivothigh, pivotlow,\ntr, swma, vwma, rising, falling\n\n#### Math (flat or math.* namespace)\nabs, max, min, round, floor, ceil, sqrt, log, exp, pow, sign,\nsin, cos, tan, asin, acos, atan, todegrees, toradians, avg, sum, random, log10\n\n#### Color\n17 named constants: color.red, color.green, color.blue, color.white, color.black, color.yellow,\ncolor.orange, color.purple, color.fuchsia, color.lime, color.maroon, color.navy, color.olive,\ncolor.silver, color.teal, color.aqua, color.gray\ncolor.new(baseColor, transparency) — transparency 0-100 (100=fully transparent)\ncolor.rgb(r, g, b, transparency?) — values 0-255 for r/g/b\ncolor.from_gradient(value, bottom_value, top_value, bottom_color, top_color) — linear interpolation\nHex literals: #RRGGBB or #RRGGBBAA\n\n#### String\nstr.tostring(value), str.tonumber(value), str.format(template, args...),\nstr.length(s), str.trim(s), str.contains(s, sub), str.startswith(s, prefix),\nstr.substring(s, start, end), str.replace_all(s, target, replacement),\nstr.upper(s), str.lower(s), str.split(s, separator) → returns an array,\nstr.match(s, regex) → returns matched string or \"\"\n\n#### Arrays\narray.new_float(size, initial_value), array.new_int(size, initial_value),\narray.new_string(size, initial_value), array.new_bool(size, initial_value),\narray.from(val1, val2, ...) — create array from values\narray.size(arr), array.get(arr, index), array.set(arr, index, value),\narray.push(arr, value), array.pop(arr), array.remove(arr, index),\narray.clear(arr), array.includes(arr, value), array.indexof(arr, value),\narray.slice(arr, start, end), array.join(arr, separator),\narray.sort(arr), array.reverse(arr),\narray.avg(arr), array.sum(arr), array.min(arr), array.max(arr)\n\n#### Tables (screen-positioned text panels)\ntable.new(position, columns, rows, bgcolor=, border_color=, border_width=, frame_color=, frame_width=) — returns table id\ntable.cell(table_id, column, row, text, text_color=, bgcolor=, text_size=, text_halign=, text_valign=)\ntable.clear(table_id, first_col, first_row, last_col?, last_row?) — remove one cell or a range of cells\ntable.delete(table_id) — remove the entire table\nPosition values: \"top_right\", \"top_left\", \"bottom_right\", \"bottom_left\", etc.\nAlignment: text.align_left → \"left\", text.align_center → \"center\", text.align_right → \"right\"\n text.align_top → \"top\", text.align_bottom → \"bottom\"\n\n#### User-defined Functions\nname(param1, param2) => expression\nname(param1, param2) =>\n statement1\n statement2\n result_expression\n\n#### Output\nplot(value, title=, color=, linewidth=, style=)\nplotshape(condition, style=, location=, color=, text=, title=)\nplotchar, plotarrow, hline(price), fill, bgcolor(color), barcolor(color)\n\n#### Pine Enum Constants (pass through as strings)\nshape.* → \"circle\", \"triangleup\", \"arrowup\", etc.\nlocation.* → \"abovebar\", \"belowbar\", \"top\", \"bottom\", \"absolute\"\nplot.style_* → \"line\", \"histogram\", \"area\", \"columns\"\nposition.* → \"top_right\", \"top_left\", \"bottom_right\", \"bottom_left\", etc.\nsize.* → \"auto\", \"tiny\", \"small\", \"normal\", \"large\", \"huge\"\ntext.align_* → \"left\", \"center\", \"right\", \"top\", \"bottom\"\n\n#### Input Parameters (all variants fully supported — return the default value at runtime)\ninput(defval, title=)\ninput.int(defval, title?, minval?, maxval?, step?)\ninput.float(defval, title?, minval?, maxval?, step?)\ninput.bool(defval, title?)\ninput.string(defval, title?, options?)\ninput.color(defval, title?)\ninput.source(defval, title?)\ninput.text_area(defval, title?)\nExtra named args like tooltip=, group=, inline=, confirm= are accepted and silently ignored.\nOptions lists in input.string/input.int are accepted and silently ignored (only the default value matters).\n\n#### Utility\nna, nz(value, replacement)\n\n### NOT SUPPORTED (do NOT use these)\n- strategy.*, alertcondition, alert\n- label, line, box, matrix\n- import/export/module/library\n- Classes or OOP constructs\n- Async/await, promises, callbacks\n- File I/O, network requests\n- request.security (stub only — returns 0)\n`;\n\nexport const FORGESCRIPT_KNOWLEDGE = `## FORGESCRIPT LANGUAGE\n\n# ForgeScript Language Specification\n\n> Canonical reference for the ForgeScript scripting language.\n> ForgeScript is a domain-specific language for financial technical indicators\n> running inside ForgeCharts.\n\n## 1. Overview\n\nForgeScript is a bar-by-bar interpreted scripting language designed for writing\ncustom technical indicators. Its syntax is intentionally Pine Script v5-compatible\nat the expression and built-in level so that users familiar with Pine can write\nForgeScript directly.\n\n## 2. Execution Model\n\n\\`\\`\\`\n[bar 0] [bar 1] [bar 2] … [bar N-1] [forming bar]\n │ │ │ │ │\nForgeScriptRuntime.execBar(bar, index)\n │\n ├─ Updates built-in series: open, high, low, close, volume, time, hl2, hlc3, ohlc4, bar_index\n ├─ Executes user code top-to-bottom\n └─ Collects plot() / plotshape() / hline() / bgcolor() / barcolor() calls → output frame\n\\`\\`\\`\n\n- The script is called **once per bar** in historical order\n- Then **once per real-time update** (forming bar)\n- All numeric values are IEEE 754 double-precision floats\n\n## 3. Series Behavior\n\nA **series** is a time-indexed sequence of values — one value per bar. All\nbuilt-in data (\\`open\\`, \\`high\\`, \\`low\\`, \\`close\\`, \\`volume\\`, \\`time\\`) are series.\nUser-assigned variables also become series implicitly.\n\nSeries values are stored in ring buffers (default capacity: 1000 bars). Access\nprevious values with lookback syntax:\n\n\\`\\`\\`\nclose[0] // current bar's close (same as just \\`close\\`)\nclose[1] // previous bar's close\nclose[n] // n bars ago\n\\`\\`\\`\n\nLookback index must be a non-negative integer. \\`close[-1]\\` is invalid.\n\n## 4. Variable Declarations\n\n### Simple assignment (re-evaluated every bar)\n\\`\\`\\`\nlength = 14\nsrc = close\nvalue = ta.sma(close, length)\n\\`\\`\\`\n\n### \\`var\\` — persistent across bars (init once on bar 0)\n\\`\\`\\`\nvar counter = 0\ncounter := counter + 1 // increments every bar\n\\`\\`\\`\n\n### \\`varip\\` — persistent, updated intra-bar\n\\`\\`\\`\nvarip tick_count = 0\ntick_count := tick_count + 1\n\\`\\`\\`\n\n### Reassignment with \\`:=\\`\n\\`\\`\\`\nx = 10 // initial assignment\nx := x + 1 // reassignment (variable must already exist)\n\\`\\`\\`\n\n**Rule**: \\`=\\` creates a new variable. \\`:=\\` modifies an existing one. Using \\`:=\\`\non an undeclared variable is a runtime error.\n\n## 5. Syntax Rules\n\n### Comments\n\\`\\`\\`\n// This is a line comment\nx = 10 // inline comment\n\\`\\`\\`\n\n### Code blocks (indentation-based)\n\\`\\`\\`\nif condition\n x = 10\n y = 20\nelse\n x = 0\n\\`\\`\\`\n\n### Operators\n\n| Category | Operators |\n|---|---|\n| Arithmetic | \\`+\\`, \\`-\\`, \\`*\\`, \\`/\\`, \\`%\\` |\n| Comparison | \\`<\\`, \\`>\\`, \\`<=\\`, \\`>=\\`, \\`==\\`, \\`!=\\` |\n| Logical | \\`and\\`, \\`or\\`, \\`not\\` |\n| Ternary | \\`condition ? then_value : else_value\\` |\n| Assignment | \\`=\\` (declare), \\`:=\\` (reassign) |\n\n### Operator Precedence (low → high)\n1. Ternary \\`? :\\`\n2. \\`or\\`\n3. \\`and\\`\n4. \\`not\\`\n5. Comparison \\`< > <= >= == !=\\`\n6. Addition \\`+ -\\`\n7. Multiplication \\`* / %\\`\n8. Unary \\`-\\`\n9. Primary (literals, identifiers, calls, index)\n\n### Literal Types\n| Type | Examples |\n|---|---|\n| Number | \\`42\\`, \\`3.14\\`, \\`.5\\` |\n| String | \\`\"hello\"\\`, \\`'world'\\` |\n| Boolean | \\`true\\`, \\`false\\` |\n| Color | \\`#FF0000\\`, \\`#FF000080\\` (with alpha) |\n| NA | \\`na\\` |\n\n## 6. Control Flow\n\n### If / Else\n\\`\\`\\`\nif ta.crossover(fast_ma, slow_ma)\n signal = 1\nelse if ta.crossunder(fast_ma, slow_ma)\n signal = -1\nelse\n signal = 0\n\\`\\`\\`\n\n### Ternary Expression\n\\`\\`\\`\ncolor_val = close > open ? color.green : color.red\n\\`\\`\\`\n\n### For Loop (numeric range)\n\\`\\`\\`\nsum = 0.0\nfor i = 0 to length - 1\n sum := sum + close[i]\n\n// With step\nfor i = 0 to 100 by 5\n // body\n\\`\\`\\`\n\n### For Loop (array iteration)\n\\`\\`\\`\nvar prices = array.new_float(0)\narray.push(prices, close)\nfor val in prices\n // val is each element\n\\`\\`\\`\n\n### While Loop\n\\`\\`\\`\nvar count = 0\nwhile count < 10\n count := count + 1\n\\`\\`\\`\n\n### Break and Continue\n\\`\\`\\`\nfor i = 0 to 100\n if i == 50\n break // exit loop\n if i % 2 == 0\n continue // skip to next iteration\n\\`\\`\\`\n\n## 7. User-Defined Functions\n\nForgeScript supports user-defined functions with Pine-style \\`=>\\` syntax.\n\n### Single-expression function\n\\`\\`\\`\nf_double(x) => x * 2\nresult = f_double(close)\n\\`\\`\\`\n\n### Multi-line function body\n\\`\\`\\`\nf_clamp(val, lo, hi) =>\n clamped = val\n if val < lo\n clamped := lo\n if val > hi\n clamped := hi\n clamped\n\\`\\`\\`\n\n### Functions with multiple parameters\n\\`\\`\\`\nf_zscore(src, length) =>\n m = sma(src, length)\n s = stdev(src, length)\n s != 0 ? (src - m) / s : 0.0\n\nzs = f_zscore(close, 20)\nplot(zs, title=\"Z-Score\")\n\\`\\`\\`\n\n**Notes:**\n- Parameters are passed by value\n- Functions can call other functions (no recursion)\n- Functions are hoisted — can be defined after use\n- The last expression in a multi-line body is the return value\n\n## 8. Declarations\n\n### indicator()\nEvery indicator script MUST begin with:\n\\`\\`\\`\nindicator(\"Title\", overlay=false, max_bars_back=500)\n\\`\\`\\`\n\nParameters:\n- \\`title\\` (string, required) — display name\n- \\`overlay\\` (bool, optional) — \\`true\\` = draw on price pane, \\`false\\` = separate pane\n- \\`shorttitle\\` (string, optional) — abbreviated name\n- \\`max_bars_back\\` (int, optional) — maximum lookback depth\n\n## 9. Special Values\n\n| Value | Description |\n|---|---|\n| \\`na\\` | Missing/undefined value (equivalent to \\`NaN\\`) |\n| \\`na(x)\\` | Returns \\`true\\` if \\`x\\` is \\`na\\` |\n| \\`nz(x)\\` | Returns \\`0\\` if \\`x\\` is \\`na\\`, otherwise \\`x\\` |\n| \\`nz(x, y)\\` | Returns \\`y\\` if \\`x\\` is \\`na\\`, otherwise \\`x\\` |\n\n## 10. Namespaces\n\n| Namespace | Purpose |\n|---|---|\n| \\`ta.*\\` | Technical analysis functions |\n| \\`math.*\\` | Mathematical functions and constants |\n| \\`color.*\\` | Color constants and constructors |\n| \\`str.*\\` | String utility functions |\n| \\`array.*\\` | Array (mutable collection) functions |\n| \\`table.*\\` | On-chart table rendering |\n| \\`input.*\\` | Typed user parameter declarations |\n| \\`syminfo.*\\` | Symbol metadata (read-only) |\n| \\`barstate.*\\` | Bar state flags (islast, isfirst, etc.) |\n| \\`timeframe.*\\` | Timeframe properties |\n| \\`request.*\\` | External data and MTF data |\n\nFunctions in \\`ta.*\\` and \\`math.*\\` can also be called without the namespace prefix:\n\\`\\`\\`\nsma(close, 14) // same as ta.sma(close, 14)\nabs(-5) // same as math.abs(-5)\n\\`\\`\\`\n\n## 11. Time Functions\n\nExtract components from a Unix millisecond timestamp (or current bar time if no arg):\n\n\\`\\`\\`\nyr = year(time) // 4-digit year, e.g. 2024\nmo = month(time) // 1–12\ndom = dayofmonth(time) // 1–31\ndow = dayofweek(time) // 1=Sunday … 7=Saturday\nhr = hour(time) // 0–23\nmn = minute(time) // 0–59\nsc = second(time) // 0–59\n\n// Construct a timestamp\nts = timestamp(2024, 1, 15, 9, 30, 0)\n\\`\\`\\`\n\n## 12. Keywords\n\nReserved words (cannot be used as variable names):\n- \\`true\\`, \\`false\\`, \\`na\\`\n- \\`and\\`, \\`or\\`, \\`not\\`\n- \\`var\\`, \\`varip\\`\n- \\`if\\`, \\`else\\`, \\`for\\`, \\`while\\`, \\`in\\`, \\`to\\`, \\`by\\`\n- \\`break\\`, \\`continue\\`\n- \\`indicator\\`, \\`input\\`, \\`plot\\`\n\n## BUILT-IN FUNCTIONS\n\n# ForgeScript Built-in Functions Reference\n\n> Complete catalog of all built-in functions, namespaces, and constants\n> available in ForgeScript. Any function NOT listed here is UNSUPPORTED.\n\n## 1. Technical Analysis — \\`ta.*\\` Namespace\n\nAll TA functions accept series data. Can be called with or without \\`ta.\\` prefix.\n\n### Moving Averages\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`ta.sma\\` / \\`sma\\` | \\`(source, length) → float\\` | Simple Moving Average |\n| \\`ta.ema\\` / \\`ema\\` | \\`(source, length) → float\\` | Exponential Moving Average |\n| \\`ta.wma\\` / \\`wma\\` | \\`(source, length) → float\\` | Weighted Moving Average |\n| \\`ta.rma\\` / \\`rma\\` | \\`(source, length) → float\\` | Wilder's Moving Average |\n| \\`ta.swma\\` / \\`swma\\` | \\`(source) → float\\` | Symmetrically Weighted Moving Average |\n| \\`ta.vwma\\` / \\`vwma\\` | \\`(source, length) → float\\` | Volume-Weighted Moving Average |\n\n### Oscillators and Indicators\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`ta.rsi\\` / \\`rsi\\` | \\`(source, length) → float\\` | Relative Strength Index [0, 100] |\n| \\`ta.macd\\` / \\`macd\\` | \\`(source, fast, slow, signal) → float\\` | Returns MACD line; stores \\`__macd_signal\\`, \\`__macd_hist\\` |\n| \\`ta.stoch\\` / \\`stoch\\` | \\`(close, high, low, length) → float\\` | Stochastic %K |\n| \\`ta.obv\\` / \\`obv\\` | \\`(close, volume) → float\\` | On-Balance Volume |\n\n### Bands and Volatility\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`ta.bb\\` / \\`bb\\` | \\`(source, length, mult?) → float\\` | Bollinger Bands — returns middle; stores \\`__bb_upper\\`, \\`__bb_lower\\` |\n| \\`ta.atr\\` / \\`atr\\` | \\`(length) → float\\` | Average True Range |\n| \\`ta.tr\\` / \\`tr\\` | \\`() → float\\` | True Range (single bar) |\n| \\`ta.stdev\\` / \\`stdev\\` | \\`(source, length) → float\\` | Standard Deviation |\n| \\`ta.dev\\` / \\`dev\\` | \\`(source, length) → float\\` | Mean Absolute Deviation |\n| \\`ta.variance\\` / \\`variance\\` | \\`(source, length) → float\\` | Variance |\n\n### Crossover and Signal Detection\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`ta.crossover\\` / \\`crossover\\` | \\`(a, b) → bool\\` | True when \\`a\\` crosses above \\`b\\` |\n| \\`ta.crossunder\\` / \\`crossunder\\` | \\`(a, b) → bool\\` | True when \\`a\\` crosses below \\`b\\` |\n| \\`ta.cross\\` / \\`cross\\` | \\`(a, b) → bool\\` | True on any cross |\n| \\`ta.rising\\` / \\`rising\\` | \\`(source, length) → bool\\` | True if source rose for \\`length\\` bars |\n| \\`ta.falling\\` / \\`falling\\` | \\`(source, length) → bool\\` | True if source fell for \\`length\\` bars |\n\n### Rolling Aggregates\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`ta.highest\\` / \\`highest\\` | \\`(source, length) → float\\` | Rolling maximum |\n| \\`ta.lowest\\` / \\`lowest\\` | \\`(source, length) → float\\` | Rolling minimum |\n| \\`ta.sum\\` / \\`sum\\` | \\`(source, length) → float\\` | Rolling sum |\n| \\`ta.cum\\` / \\`cum\\` | \\`(source) → float\\` | Cumulative sum from bar 0 |\n| \\`ta.correlation\\` / \\`correlation\\` | \\`(src1, src2, length) → float\\` | Pearson correlation |\n\n### Change and Momentum\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`ta.change\\` / \\`change\\` | \\`(source, length?) → float\\` | \\`source - source[length]\\` (default length=1) |\n| \\`ta.mom\\` / \\`mom\\` | \\`(source, length) → float\\` | Momentum = change over N bars |\n\n### Lookback Utilities\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`ta.valuewhen\\` / \\`valuewhen\\` | \\`(condition, source, occurrence) → float\\` | Value at Nth true condition |\n| \\`ta.barssince\\` / \\`barssince\\` | \\`(condition) → int\\` | Bars since condition was last true |\n| \\`ta.pivothigh\\` / \\`pivothigh\\` | \\`(source, leftbars, rightbars) → float|na\\` | Pivot high detection |\n| \\`ta.pivotlow\\` / \\`pivotlow\\` | \\`(source, leftbars, rightbars) → float|na\\` | Pivot low detection |\n\n---\n\n## 2. Math — \\`math.*\\` Namespace\n\nCan be called with or without \\`math.\\` prefix.\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`math.abs\\` / \\`abs\\` | \\`(x) → float\\` | Absolute value |\n| \\`math.max\\` / \\`max\\` | \\`(...args) → float\\` | Maximum of arguments |\n| \\`math.min\\` / \\`min\\` | \\`(...args) → float\\` | Minimum of arguments |\n| \\`math.round\\` / \\`round\\` | \\`(x) → float\\` | Round to nearest integer |\n| \\`math.floor\\` / \\`floor\\` | \\`(x) → float\\` | Round down |\n| \\`math.ceil\\` / \\`ceil\\` | \\`(x) → float\\` | Round up |\n| \\`math.sqrt\\` / \\`sqrt\\` | \\`(x) → float\\` | Square root |\n| \\`math.log\\` / \\`log\\` | \\`(x) → float\\` | Natural logarithm |\n| \\`math.log10\\` / \\`log10\\` | \\`(x) → float\\` | Base-10 logarithm |\n| \\`math.exp\\` / \\`exp\\` | \\`(x) → float\\` | e^x |\n| \\`math.pow\\` / \\`pow\\` | \\`(base, exp) → float\\` | Exponentiation |\n| \\`math.sign\\` / \\`sign\\` | \\`(x) → float\\` | Sign: -1, 0, or 1 |\n| \\`math.sin\\` / \\`sin\\` | \\`(x) → float\\` | Sine (radians) |\n| \\`math.cos\\` / \\`cos\\` | \\`(x) → float\\` | Cosine (radians) |\n| \\`math.tan\\` / \\`tan\\` | \\`(x) → float\\` | Tangent (radians) |\n| \\`math.asin\\` / \\`asin\\` | \\`(x) → float\\` | Arc sine |\n| \\`math.acos\\` / \\`acos\\` | \\`(x) → float\\` | Arc cosine |\n| \\`math.atan\\` / \\`atan\\` | \\`(x) → float\\` | Arc tangent |\n| \\`math.todegrees\\` / \\`todegrees\\` | \\`(radians) → float\\` | Radians to degrees |\n| \\`math.toradians\\` / \\`toradians\\` | \\`(degrees) → float\\` | Degrees to radians |\n| \\`math.avg\\` / \\`avg\\` | \\`(...args) → float\\` | Average of arguments |\n| \\`math.random\\` / \\`random\\` | \\`() → float\\` | Random number [0, 1) |\n\n### Constants\n\n| Constant | Value |\n|---|---|\n| \\`math.pi\\` | 3.14159265358979 |\n| \\`math.e\\` | 2.71828182845905 |\n\n---\n\n## 3. Color — \\`color.*\\` Namespace\n\n### Named Color Constants\n\n| Constant | Hex |\n|---|---|\n| \\`color.red\\` | \\`#FF0000\\` |\n| \\`color.green\\` | \\`#00FF00\\` |\n| \\`color.blue\\` | \\`#0000FF\\` |\n| \\`color.white\\` | \\`#FFFFFF\\` |\n| \\`color.black\\` | \\`#000000\\` |\n| \\`color.yellow\\` | \\`#FFFF00\\` |\n| \\`color.orange\\` | \\`#FF9800\\` |\n| \\`color.purple\\` | \\`#9C27B0\\` |\n| \\`color.aqua\\` | \\`#00BCD4\\` |\n| \\`color.gray\\` | \\`#787B86\\` |\n| \\`color.silver\\` | \\`#9E9E9E\\` |\n| \\`color.lime\\` | \\`#8BC34A\\` |\n| \\`color.maroon\\` | \\`#880E4F\\` |\n| \\`color.navy\\` | \\`#311B92\\` |\n| \\`color.olive\\` | \\`#808000\\` |\n| \\`color.teal\\` | \\`#009688\\` |\n| \\`color.fuchsia\\` | \\`#E040FB\\` |\n\n### Color Functions\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`color.new\\` | \\`(baseColor, transparency) → string\\` | Add transparency to a color. \\`transparency\\` is 0–100 (0 = opaque, 100 = invisible) |\n| \\`color.rgb\\` | \\`(r, g, b, transp?) → string\\` | Create color from RGBA components (0–255 each; transp 0–100) |\n| \\`color.from_gradient\\` | \\`(value, bottom_value, top_value, bottom_color, top_color) → string\\` | Interpolate between two colors based on value position in [bottom_value, top_value] |\n\n### Hex Literals\n\\`\\`\\`\nc = #2962FF // RGB\nc = #2962FF80 // RGBA (80 = hex alpha)\n\\`\\`\\`\n\n---\n\n## 4. String — \\`str.*\\` Namespace\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`str.tostring\\` | \\`(value) → string\\` | Convert any value to string |\n| \\`str.tonumber\\` | \\`(value) → float\\` | Parse string to number (NaN if invalid) |\n| \\`str.format\\` | \\`(template, ...args) → string\\` | Format with \\`{0}\\`, \\`{1}\\` placeholders |\n| \\`str.length\\` | \\`(s) → int\\` | String length |\n| \\`str.trim\\` | \\`(s) → string\\` | Remove leading/trailing whitespace |\n| \\`str.contains\\` | \\`(s, sub) → bool\\` | True if \\`s\\` contains \\`sub\\` |\n| \\`str.substring\\` | \\`(s, start, end?) → string\\` | Extract substring |\n| \\`str.replace_all\\` | \\`(s, target, replacement) → string\\` | Replace all occurrences |\n| \\`str.upper\\` | \\`(s) → string\\` | Convert to uppercase |\n| \\`str.lower\\` | \\`(s) → string\\` | Convert to lowercase |\n| \\`str.split\\` | \\`(s, sep?) → array\\` | Split into array of substrings (default sep = \\`\",\"\\`) |\n| \\`str.startswith\\` | \\`(s, prefix) → bool\\` | True if \\`s\\` starts with \\`prefix\\` |\n| \\`str.match\\` | \\`(s, pattern) → string\\` | Return first regex match, or \\`\"\"\\` if none |\n\n---\n\n## 5. Array — \\`array.*\\` Namespace\n\nArrays are mutable ordered collections. Use \\`var\\` to persist across bars.\n\n\\`\\`\\`\nvar vals = array.new_float(0) // empty float array\narray.push(vals, close) // append current close\n\\`\\`\\`\n\n### Creation\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`array.new\\` | \\`(size, init_val) → array\\` | Create array of given size |\n| \\`array.new_float\\` | \\`(size, init_val?) → array\\` | Create float array |\n| \\`array.new_int\\` | \\`(size, init_val?) → array\\` | Create int array |\n| \\`array.new_string\\` | \\`(size, init_val?) → array\\` | Create string array |\n| \\`array.new_bool\\` | \\`(size, init_val?) → array\\` | Create bool array |\n| \\`array.from\\` | \\`(v1, v2, ...) → array\\` | Create from literal values |\n\n### Access and Mutation\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`array.size\\` | \\`(arr) → int\\` | Number of elements |\n| \\`array.get\\` | \\`(arr, index) → value\\` | Get element at index |\n| \\`array.set\\` | \\`(arr, index, val) → void\\` | Set element at index |\n| \\`array.push\\` | \\`(arr, val) → void\\` | Append element |\n| \\`array.pop\\` | \\`(arr) → value\\` | Remove and return last element |\n| \\`array.remove\\` | \\`(arr, index) → value\\` | Remove element at index |\n| \\`array.clear\\` | \\`(arr) → void\\` | Remove all elements |\n\n### Search and Transform\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`array.includes\\` | \\`(arr, val) → bool\\` | True if array contains value |\n| \\`array.indexof\\` | \\`(arr, val) → int\\` | First index of value (-1 if not found) |\n| \\`array.slice\\` | \\`(arr, start, end) → array\\` | Sub-array |\n| \\`array.join\\` | \\`(arr, sep?) → string\\` | Join elements into string |\n| \\`array.sort\\` | \\`(arr) → void\\` | Sort in place (ascending) |\n| \\`array.reverse\\` | \\`(arr) → void\\` | Reverse in place |\n\n### Aggregates\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`array.avg\\` | \\`(arr) → float\\` | Average of all elements |\n| \\`array.sum\\` | \\`(arr) → float\\` | Sum of all elements |\n| \\`array.min\\` | \\`(arr) → float\\` | Minimum element |\n| \\`array.max\\` | \\`(arr) → float\\` | Maximum element |\n\n---\n\n## 6. Table — \\`table.*\\` Namespace\n\nTables render a grid of text cells on the chart. Use \\`var\\` to persist.\n\n\\`\\`\\`\nvar tbl = table.new(position.top_right, 3, 3,\n bgcolor=color.black, border_color=color.gray, border_width=1)\ntable.cell(tbl, 0, 0, \"Label\", text_color=color.white, text_size=size.small)\n\\`\\`\\`\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`table.new\\` | \\`(position, columns, rows, bgcolor?, border_color?, border_width?, frame_color?, frame_width?) → table\\` | Create a table |\n| \\`table.cell\\` | \\`(tbl, column, row, text, text_color?, bgcolor?, text_size?, text_halign?, text_valign?) → void\\` | Set cell content |\n| \\`table.clear\\` | \\`(tbl, column, row) → void\\` | Clear a single cell |\n| \\`table.delete\\` | \\`(tbl) → void\\` | Delete the table |\n\n**Position:** use \\`position.*\\` constants — \\`position.top_right\\`, \\`position.top_left\\`, etc.\n**Text size:** use \\`size.*\\` constants — \\`size.tiny\\`, \\`size.small\\`, \\`size.normal\\`, \\`size.large\\`, \\`size.huge\\`\n**Alignment:** \\`\"left\"\\`, \\`\"center\"\\`, \\`\"right\"\\` for \\`text_halign\\`; \\`\"top\"\\`, \\`\"center\"\\`, \\`\"bottom\"\\` for \\`text_valign\\`\n\n---\n\n## 7. Input — \\`input.*\\` Namespace\n\nAll input functions return the default value at runtime (parameters are for UI configuration).\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`input\\` | \\`(defval, title?) → value\\` | Generic parameter |\n| \\`input.int\\` | \\`(defval, title?, minval?, maxval?, step?) → int\\` | Integer parameter |\n| \\`input.float\\` | \\`(defval, title?, minval?, maxval?, step?) → float\\` | Float parameter |\n| \\`input.bool\\` | \\`(defval, title?) → bool\\` | Boolean toggle |\n| \\`input.string\\` | \\`(defval, title?, options?) → string\\` | String/dropdown parameter |\n| \\`input.color\\` | \\`(defval, title?) → color\\` | Color picker (returns the default color) |\n| \\`input.source\\` | \\`(defval, title?) → series\\` | Source selector (returns the default series) |\n| \\`input.text_area\\` | \\`(defval, title?) → string\\` | Multi-line text input |\n\n**IMPORTANT:** All \\`input.*\\` variants are fully supported. NEVER downgrade \\`input.int/bool/float/color\\` to plain \\`input()\\`. Extra named args (\\`tooltip\\`, \\`group\\`, \\`inline\\`, \\`confirm\\`, \\`minval\\`, \\`maxval\\`, \\`step\\`, \\`options\\`) are silently accepted.\n\n---\n\n## 8. Symbol Info — \\`syminfo.*\\` (Read-Only)\n\n| Property | Type | Description |\n|---|---|---|\n| \\`syminfo.tickerid\\` | string | Full ticker with exchange, e.g. \\`\"CME:ES1!\"\\` |\n| \\`syminfo.ticker\\` | string | Ticker without exchange, e.g. \\`\"ES1!\"\\` |\n| \\`syminfo.mintick\\` | float | Minimum price increment |\n| \\`syminfo.pointvalue\\` | float | Dollar value per point |\n| \\`syminfo.currency\\` | string | Quote currency |\n| \\`syminfo.type\\` | string | \\`\"futures\"\\`, \\`\"forex\"\\`, \\`\"crypto\"\\`, \\`\"stock\"\\` |\n| \\`syminfo.session\\` | string | Active session, e.g. \\`\"0830-1515\"\\` |\n| \\`syminfo.timezone\\` | string | IANA timezone, e.g. \\`\"America/Chicago\"\\` |\n\n---\n\n## 9. Bar State — \\`barstate.*\\` (Read-Only)\n\n| Property | Type | Description |\n|---|---|---|\n| \\`barstate.islast\\` | bool | True on the most recent bar |\n| \\`barstate.isfirst\\` | bool | True on bar 0 |\n| \\`barstate.isconfirmed\\` | bool | True — all historical bars are confirmed |\n| \\`barstate.isnew\\` | bool | True — each bar is new in per-bar execution |\n| \\`barstate.isrealtime\\` | bool | False — ForgeScript runs on historical data |\n| \\`barstate.ishistory\\` | bool | True |\n\n---\n\n## 10. Timeframe — \\`timeframe.*\\` (Read-Only)\n\n| Property | Type | Description |\n|---|---|---|\n| \\`timeframe.period\\` | string | Current timeframe period string, e.g. \\`\"1\"\\`, \\`\"D\"\\` |\n| \\`timeframe.multiplier\\` | int | Numeric multiplier, e.g. \\`1\\`, \\`60\\` |\n| \\`timeframe.isintraday\\` | bool | True |\n| \\`timeframe.isdaily\\` | bool | False |\n| \\`timeframe.isweekly\\` | bool | False |\n| \\`timeframe.ismonthly\\` | bool | False |\n\n---\n\n## 11. Time Functions (flat calls)\n\nExtract date/time components from a Unix millisecond timestamp.\nAll functions accept an optional \\`time\\` argument (defaults to current bar's \\`time\\`).\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`year\\` | \\`(time?) → int\\` | 4-digit year, e.g. 2024 |\n| \\`month\\` | \\`(time?) → int\\` | Month 1–12 |\n| \\`dayofmonth\\` | \\`(time?) → int\\` | Day of month 1–31 |\n| \\`dayofweek\\` | \\`(time?) → int\\` | Day of week: 1=Sunday … 7=Saturday |\n| \\`hour\\` | \\`(time?) → int\\` | Hour 0–23 (UTC) |\n| \\`minute\\` | \\`(time?) → int\\` | Minute 0–59 |\n| \\`second\\` | \\`(time?) → int\\` | Second 0–59 |\n| \\`timestamp\\` | \\`(year, month, day, hour?, minute?, second?) → int\\` | Construct Unix ms timestamp |\n\n\\`\\`\\`\nif hour(time) == 9 and minute(time) == 30\n plotshape(true, style=\"circle\", location=\"abovebar\", color=color.yellow, text=\"Open\")\n\nsessionStart = timestamp(year(time), month(time), dayofmonth(time), 9, 30, 0)\n\\`\\`\\`\n\n---\n\n## 12. Enum-Like Namespaces\n\nThese namespaces return their property name as a string constant.\n\n| Namespace | Example Values |\n|---|---|\n| \\`position.*\\` | \\`top_right\\`, \\`top_left\\`, \\`top_center\\`, \\`middle_left\\`, \\`middle_center\\`, \\`middle_right\\`, \\`bottom_left\\`, \\`bottom_center\\`, \\`bottom_right\\` |\n| \\`size.*\\` | \\`tiny\\`, \\`small\\`, \\`normal\\`, \\`large\\`, \\`huge\\`, \\`auto\\` |\n| \\`shape.*\\` | \\`circle\\`, \\`square\\`, \\`diamond\\`, \\`triangleup\\`, \\`triangledown\\`, \\`flag\\`, \\`labelup\\`, \\`labeldown\\`, \\`xcross\\`, \\`cross\\`, \\`arrowup\\`, \\`arrowdown\\` |\n| \\`location.*\\` | \\`abovebar\\`, \\`belowbar\\`, \\`top\\`, \\`bottom\\`, \\`absolute\\` |\n| \\`text.*\\` | \\`align_left\\` → \\`\"left\"\\`, \\`align_center\\` → \\`\"center\"\\`, \\`align_right\\` → \\`\"right\"\\`, \\`align_top\\` → \\`\"top\"\\`, \\`align_bottom\\` → \\`\"bottom\"\\` |\n| \\`plot.*\\` | \\`style_line\\` → \\`\"line\"\\`, \\`style_histogram\\` → \\`\"histogram\"\\`, \\`style_circles\\` → \\`\"circles\"\\`, \\`style_area\\` → \\`\"area\"\\`, \\`style_columns\\` → \\`\"columns\"\\`, \\`style_stepline\\` → \\`\"stepline\"\\` |\n\n---\n\n## 13. Built-in Data Series\n\nAlways available without declaration:\n\n| Name | Type | Description |\n|---|---|---|\n| \\`open\\` | series float | Bar open price |\n| \\`high\\` | series float | Bar high price |\n| \\`low\\` | series float | Bar low price |\n| \\`close\\` | series float | Bar close price |\n| \\`volume\\` | series float | Bar volume |\n| \\`time\\` | series int | Bar open time (Unix milliseconds) |\n| \\`hl2\\` | series float | \\`(high + low) / 2\\` |\n| \\`hlc3\\` | series float | \\`(high + low + close) / 3\\` |\n| \\`ohlc4\\` | series float | \\`(open + high + low + close) / 4\\` |\n| \\`bar_index\\` | int | Zero-based bar count |\n\n---\n\n## 14. Utility Functions\n\n| Function | Signature | Description |\n|---|---|---|\n| \\`indicator\\` | \\`(title, overlay?, precision?) → void\\` | Declare indicator name and settings |\n| \\`na\\` | \\`(value?) → bool|float\\` | Test if value is na, or the na constant itself |\n| \\`nz\\` | \\`(value, replacement?) → float\\` | Replace na with 0 or custom replacement |\n\n\n## 9. Data Requests (\\`request.*\\`)\n\nFunctions for accessing external data and multi-timeframe (MTF) series.\n\n| Function | Description |\n|----------|-------------|\n| \\`request.security(symbol, timeframe, expression)\\` | Evaluates \\`expression\\` on the specified \\`symbol\\` and \\`timeframe\\` (e.g., \\`\"AAPL\"\\`, \\`\"D\"\\`, \\`close\\`). Returns \\`NaN\\` if the host has not loaded the requested MTF data. |\n| \\`request.data(datasetName, column)\\` | Looks up the value of \\`column\\` in a user-imported dataset named \\`datasetName\\` at the current bar's time. If \\`column\\` is omitted, defaults to \\`\"value\"\\`. Returns \\`NaN\\` if the dataset or column does not exist. |\n\n## EXAMPLES — BASIC\n\n# ForgeScript Examples — Basic Indicators\n\nThese examples demonstrate correct ForgeScript syntax for common indicators.\nAll examples are valid, tested ForgeScript code.\n\n---\n\n## 1. Simple Moving Average (SMA)\n\n\\`\\`\\`forgescript\nindicator(\"SMA Indicator\", overlay=true)\nlength = input(14, title=\"Length\")\nsrc = close\nsmaVal = sma(src, length)\nplot(smaVal, title=\"SMA\", color=#2196F3, linewidth=2)\n\\`\\`\\`\n\n**Key points:**\n- \\`input()\\` lets users configure parameters\n- \\`sma()\\` computes a rolling simple moving average\n- \\`plot()\\` draws the result on the chart\n- \\`overlay=true\\` renders on the price pane\n\n---\n\n## 2. Exponential Moving Average (EMA)\n\n\\`\\`\\`forgescript\nindicator(\"EMA Crossover\", overlay=true)\nfastLen = input(9, title=\"Fast EMA\")\nslowLen = input(21, title=\"Slow EMA\")\nfastEma = ema(close, fastLen)\nslowEma = ema(close, slowLen)\nplot(fastEma, title=\"Fast EMA\", color=#2196F3, linewidth=2)\nplot(slowEma, title=\"Slow EMA\", color=#FF6D00, linewidth=2)\n\\`\\`\\`\n\n---\n\n## 3. Relative Strength Index (RSI)\n\n\\`\\`\\`forgescript\nindicator(\"RSI\", overlay=false)\nlength = input(14, title=\"RSI Period\")\nsrc = close\nrsiVal = rsi(src, length)\nplot(rsiVal, title=\"RSI\", color=#2196F3, linewidth=2)\nhline(70, title=\"Overbought\", color=#FF0000, linestyle=\"dashed\")\nhline(30, title=\"Oversold\", color=#00FF00, linestyle=\"dashed\")\nhline(50, title=\"Midline\", color=#787B86, linestyle=\"dotted\")\n\\`\\`\\`\n\n**Key points:**\n- \\`overlay=false\\` renders in a separate sub-pane\n- \\`hline()\\` draws horizontal reference lines\n- RSI ranges from 0 to 100\n\n---\n\n## 4. MACD (Moving Average Convergence Divergence)\n\n\\`\\`\\`forgescript\nindicator(\"MACD\", overlay=false)\nfastLen = input(12, title=\"Fast Length\")\nslowLen = input(26, title=\"Slow Length\")\nsignalLen = input(9, title=\"Signal Length\")\nmacdVal = macd(close, fastLen, slowLen, signalLen)\nplot(macdVal, title=\"MACD\", color=#2196F3, linewidth=2)\nplot(__macd_signal, title=\"Signal\", color=#FF6D00, linewidth=1)\nplot(__macd_hist, title=\"Histogram\", color=#26a69a, style=\"histogram\")\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\n\\`\\`\\`\n\n**Key points:**\n- \\`macd()\\` returns the MACD line value\n- \\`__macd_signal\\` and \\`__macd_hist\\` are automatically populated after \\`macd()\\` is called\n- Use \\`style=\"histogram\"\\` for the histogram bars\n\n---\n\n## 5. Bollinger Bands\n\n\\`\\`\\`forgescript\nindicator(\"Bollinger Bands\", overlay=true)\nlength = input(20, title=\"Length\")\nmult = input(2, title=\"Multiplier\")\nbasis = sma(close, length)\ndevVal = mult * stdev(close, length)\nupper = basis + devVal\nlower = basis - devVal\np1 = plot(upper, title=\"Upper\", color=#FF000080)\np2 = plot(lower, title=\"Lower\", color=#00FF0080)\nfill(p1, p2, color=#2196F320, title=\"BB Zone\")\nplot(basis, title=\"Basis\", color=#FF6D00, linewidth=2)\n\\`\\`\\`\n\n**Key points:**\n- \\`stdev()\\` computes rolling standard deviation\n- \\`fill()\\` shades the area between two plots\n- Color alpha suffix (\\`80\\`, \\`20\\`) controls transparency\n\n---\n\n## 6. Simple Crossover Signal\n\n\\`\\`\\`forgescript\nindicator(\"Golden/Death Cross\", overlay=true)\nfast = sma(close, 50)\nslow = sma(close, 200)\nplot(fast, title=\"SMA 50\", color=#2196F3, linewidth=2)\nplot(slow, title=\"SMA 200\", color=#FF6D00, linewidth=2)\nplotshape(crossover(fast, slow), style=\"triangleup\", location=\"belowbar\", color=#00FF00, text=\"Golden\")\nplotshape(crossunder(fast, slow), style=\"triangledown\", location=\"abovebar\", color=#FF0000, text=\"Death\")\n\\`\\`\\`\n\n**Key points:**\n- \\`crossover(a, b)\\` is true when \\`a\\` crosses above \\`b\\`\n- \\`crossunder(a, b)\\` is true when \\`a\\` crosses below \\`b\\`\n- \\`plotshape()\\` only emits a marker when the condition is true\n\n---\n\n## 7. Average True Range (ATR)\n\n\\`\\`\\`forgescript\nindicator(\"ATR\", overlay=false)\nlength = input(14, title=\"ATR Period\")\natrVal = atr(length)\nplot(atrVal, title=\"ATR\", color=#FF6D00, linewidth=2)\n\\`\\`\\`\n\n---\n\n## 8. Stochastic Oscillator\n\n\\`\\`\\`forgescript\nindicator(\"Stochastic\", overlay=false)\nkLen = input(14, title=\"%K Length\")\nkVal = stoch(close, high, low, kLen)\ndVal = sma(kVal, 3)\nplot(kVal, title=\"%K\", color=#2196F3, linewidth=2)\nplot(dVal, title=\"%D\", color=#FF6D00, linewidth=1)\nhline(80, title=\"Overbought\", color=#FF0000, linestyle=\"dashed\")\nhline(20, title=\"Oversold\", color=#00FF00, linestyle=\"dashed\")\n\\`\\`\\`\n\n---\n\n## 9. On-Balance Volume (OBV)\n\n\\`\\`\\`forgescript\nindicator(\"OBV\", overlay=false)\nobvVal = obv()\nobvSma = sma(obvVal, 20)\nplot(obvVal, title=\"OBV\", color=#2196F3, linewidth=2)\nplot(obvSma, title=\"OBV SMA\", color=#FF6D00, linewidth=1)\n\\`\\`\\`\n\n---\n\n## 10. Stateful Accumulator with var\n\n\\`\\`\\`forgescript\nindicator(\"Cumulative Delta\", overlay=false)\nvar cumDelta = 0\ndelta = close - open\ncumDelta := cumDelta + delta\nplot(cumDelta, title=\"Cum Delta\", color=#2196F3, linewidth=2)\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\n\\`\\`\\`\n\n**Key points:**\n- \\`var cumDelta = 0\\` initializes once (persists across bars)\n- \\`cumDelta := cumDelta + delta\\` reassigns on each bar\n- The \\`=\\` is for first declaration, \\`:=\\` is for reassignment\n\n---\n\n## 11. Momentum\n\n\\`\\`\\`forgescript\nindicator(\"Momentum\", overlay=false)\nlength = input(10, title=\"Length\")\nmomVal = mom(close, length)\nplot(momVal, title=\"Momentum\", color=#2196F3, linewidth=2)\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\nbgcolor(momVal > 0 ? #00FF0010 : #FF000010)\n\\`\\`\\`\n\n---\n\n## 12. Price Change\n\n\\`\\`\\`forgescript\nindicator(\"Daily Change\", overlay=false)\nchg = change(close)\nplot(chg, title=\"Change\", color=#2196F3, style=\"histogram\")\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\nbarcolor(chg > 0 ? #26a69a : #ef5350)\n\\`\\`\\`\n\n## EXAMPLES — ADVANCED\n\n# ForgeScript Examples — Advanced Indicators\n\nThese examples demonstrate more complex ForgeScript patterns.\nAll examples are valid, tested ForgeScript code.\n\n---\n\n## 1. Multi-Indicator Dashboard\n\n\\`\\`\\`forgescript\nindicator(\"Trend Dashboard\", overlay=false)\n\n// Moving averages for trend\nfast = ema(close, 9)\nslow = ema(close, 21)\n\n// Momentum\nrsiVal = rsi(close, 14)\nmomVal = mom(close, 10)\n\n// Trend score: +1 per bullish signal\nscore = 0\nif fast > slow\n score := score + 1\nif rsiVal > 50\n score := score + 1\nif momVal > 0\n score := score + 1\n\nplot(score, title=\"Trend Score\", color=#2196F3, style=\"histogram\")\nhline(0, title=\"Neutral\", color=#787B86, linestyle=\"dotted\")\nhline(3, title=\"Full Bull\", color=#00FF00, linestyle=\"dashed\")\nbgcolor(score == 3 ? #00FF0015 : score == 0 ? #FF000015 : na)\n\\`\\`\\`\n\n**Key points:**\n- Combine multiple indicators into a single score\n- Use \\`if\\` blocks to conditionally update \\`score\\` with \\`:=\\`\n- Initial \\`score = 0\\` uses \\`=\\`, subsequent updates use \\`:=\\`\n\n---\n\n## 2. Volatility-Adjusted Bands\n\n\\`\\`\\`forgescript\nindicator(\"Keltner Channels\", overlay=true)\nlength = input(20, title=\"Length\")\nmult = input(1.5, title=\"ATR Multiplier\")\n\nbasis = ema(close, length)\natrVal = atr(length)\nupper = basis + mult * atrVal\nlower = basis - mult * atrVal\n\np1 = plot(upper, title=\"Upper\", color=#FF000060)\np2 = plot(lower, title=\"Lower\", color=#00FF0060)\nfill(p1, p2, color=#2196F315, title=\"Channel\")\nplot(basis, title=\"Basis\", color=#FF6D00, linewidth=2)\n\n// Breakout detection\nplotshape(close > upper, style=\"triangleup\", location=\"belowbar\", color=#00FF00, text=\"Break\")\nplotshape(close < lower, style=\"triangledown\", location=\"abovebar\", color=#FF0000, text=\"Break\")\n\\`\\`\\`\n\n---\n\n## 3. RSI Divergence Detector\n\n\\`\\`\\`forgescript\nindicator(\"RSI with Divergence\", overlay=false)\nlength = input(14, title=\"RSI Length\")\nlookback = input(5, title=\"Lookback\")\n\nrsiVal = rsi(close, length)\n\n// Detect potential bullish divergence:\n// Price making lower lows while RSI making higher lows\npriceLow = lowest(close, lookback)\nrsiLow = lowest(rsiVal, lookback)\nprevPriceLow = lowest(close[lookback], lookback)\nprevRsiLow = lowest(rsiVal[lookback], lookback)\n\nbullDiv = priceLow < prevPriceLow and rsiLow > prevRsiLow\n\nplot(rsiVal, title=\"RSI\", color=#2196F3, linewidth=2)\nhline(70, title=\"Overbought\", color=#FF0000, linestyle=\"dashed\")\nhline(30, title=\"Oversold\", color=#00FF00, linestyle=\"dashed\")\nplotshape(bullDiv, style=\"diamond\", location=\"bottom\", color=#00FF00, text=\"Div\")\nbgcolor(bullDiv ? #00FF0020 : na)\n\\`\\`\\`\n\n---\n\n## 4. Custom Signal with Multiple Confirmations\n\n\\`\\`\\`forgescript\nindicator(\"Triple Confirmation\", overlay=true)\n\n// Signal 1: EMA crossover\nfast = ema(close, 9)\nslow = ema(close, 21)\nemaCross = crossover(fast, slow)\n\n// Signal 2: RSI confirmation\nrsiVal = rsi(close, 14)\nrsiBull = rsiVal > 50\n\n// Signal 3: Volume confirmation\nvolSma = sma(volume, 20)\nvolSpike = volume > 1.5 * volSma\n\n// Combined signal\nbuySignal = emaCross and rsiBull and volSpike\n\nplot(fast, title=\"Fast EMA\", color=#2196F3, linewidth=1)\nplot(slow, title=\"Slow EMA\", color=#FF6D00, linewidth=1)\nplotshape(buySignal, style=\"label_up\", location=\"belowbar\", color=#00FF00, text=\"BUY\")\nbgcolor(buySignal ? #00FF0020 : na)\n\\`\\`\\`\n\n---\n\n## 5. Layered Plots with Fills\n\n\\`\\`\\`forgescript\nindicator(\"Triple EMA Ribbon\", overlay=true)\nema8 = ema(close, 8)\nema13 = ema(close, 13)\nema21 = ema(close, 21)\nema55 = ema(close, 55)\n\np1 = plot(ema8, title=\"EMA 8\", color=#4CAF50)\np2 = plot(ema13, title=\"EMA 13\", color=#8BC34A)\np3 = plot(ema21, title=\"EMA 21\", color=#FF9800)\np4 = plot(ema55, title=\"EMA 55\", color=#F44336)\n\nfill(p1, p2, color=#4CAF5020)\nfill(p2, p3, color=#8BC34A20)\nfill(p3, p4, color=#FF980020)\n\\`\\`\\`\n\n---\n\n## 6. Dynamic Support/Resistance\n\n\\`\\`\\`forgescript\nindicator(\"Pivot Points\", overlay=true)\nleftBars = input(5, title=\"Left Bars\")\nrightBars = input(5, title=\"Right Bars\")\n\npvtHigh = pivothigh(high, leftBars, rightBars)\npvtLow = pivotlow(low, leftBars, rightBars)\n\nplot(pvtHigh, title=\"Pivot High\", color=#FF0000, style=\"circles\", linewidth=3)\nplot(pvtLow, title=\"Pivot Low\", color=#00FF00, style=\"circles\", linewidth=3)\n\\`\\`\\`\n\n**Key points:**\n- \\`pivothigh()\\` and \\`pivotlow()\\` return \\`NaN\\` when no pivot is detected\n- \\`NaN\\` values are automatically filtered from plot output\n- \\`style=\"circles\"\\` renders only at pivot points\n\n---\n\n## 7. Volume Profile Indicator\n\n\\`\\`\\`forgescript\nindicator(\"Volume Analysis\", overlay=false)\nvolSma = sma(volume, 20)\nvolRatio = volume / volSma\n\nplot(volRatio, title=\"Vol Ratio\", color=#2196F3, style=\"histogram\")\nhline(1.0, title=\"Average\", color=#787B86, linestyle=\"dashed\")\nhline(2.0, title=\"High Volume\", color=#FF0000, linestyle=\"dashed\")\n\nbarcolor(volRatio > 2.0 ? #FF0000 : volRatio > 1.5 ? #FF6D00 : na)\nbgcolor(volRatio > 2.0 ? #FF000015 : na)\n\\`\\`\\`\n\n---\n\n## 8. Rolling High/Low Channel\n\n\\`\\`\\`forgescript\nindicator(\"Donchian Channel\", overlay=true)\nlength = input(20, title=\"Channel Length\")\n\nupperCh = highest(high, length)\nlowerCh = lowest(low, length)\nmidCh = (upperCh + lowerCh) / 2\n\np1 = plot(upperCh, title=\"Upper\", color=#FF0000)\np2 = plot(lowerCh, title=\"Lower\", color=#00FF00)\nfill(p1, p2, color=#2196F310)\nplot(midCh, title=\"Mid\", color=#FF6D00, linewidth=2, style=\"stepline\")\n\\`\\`\\`\n\n---\n\n## 9. Correlation Indicator\n\n\\`\\`\\`forgescript\nindicator(\"Price-Volume Correlation\", overlay=false)\nlength = input(20, title=\"Length\")\ncorrVal = correlation(close, volume, length)\n\nplot(corrVal, title=\"Correlation\", color=#2196F3, linewidth=2)\nhline(0.5, title=\"Strong Positive\", color=#00FF00, linestyle=\"dashed\")\nhline(-0.5, title=\"Strong Negative\", color=#FF0000, linestyle=\"dashed\")\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\nbgcolor(corrVal > 0.5 ? #00FF0015 : corrVal < -0.5 ? #FF000015 : na)\n\\`\\`\\`\n\n---\n\n## 10. Momentum with Lookback Comparison\n\n\\`\\`\\`forgescript\nindicator(\"Rate of Change\", overlay=false)\nlength = input(12, title=\"ROC Length\")\nroc = (close - close[length]) / close[length] * 100\n\nplot(roc, title=\"ROC %\", color=#2196F3, linewidth=2)\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\n\n// Color bars based on momentum direction\nbarcolor(roc > 0 and roc > roc[1] ? #00FF00 : roc < 0 and roc < roc[1] ? #FF0000 : na)\n\n// Mark extreme moves\nplotshape(roc > 10, style=\"flag\", location=\"top\", color=#00FF00, text=\"Strong\")\nplotshape(roc < -10, style=\"flag\", location=\"bottom\", color=#FF0000, text=\"Weak\")\n\\`\\`\\`\n\n## PLOTTING\n\n# ForgeScript Plotting & Output Functions\n\nForgeScript output functions emit visual data from each bar execution.\nEvery output function is called once per bar during the bar-by-bar execution loop.\n\n---\n\n## 1. plot()\n\nDraw a continuous series line on the chart.\n\n\\`\\`\\`\nplot(value, title=, color=, linewidth=, style=)\n\\`\\`\\`\n\n| Parameter | Type | Default | Description |\n|-------------|--------|-------------|-------------|\n| value | number | required | Series value to plot |\n| title | string | \"Plot N\" | Legend label |\n| color | string | — | Hex color \\`#RRGGBB\\` or \\`#RRGGBBAA\\` |\n| linewidth | number | 1 | Line thickness in pixels |\n| style | string | \"line\" | Drawing style (see below) |\n\n**Supported styles:**\n\\`\"line\"\\`, \\`\"histogram\"\\`, \\`\"circles\"\\`, \\`\"cross\"\\`, \\`\"area\"\\`, \\`\"columns\"\\`, \\`\"stepline\"\\`, \\`\"stepline_diamond\"\\`\n\n**Returns:** the \\`value\\` parameter (number).\n\n**Example:**\n\\`\\`\\`forgescript\nindicator(\"SMA Plot\", overlay=true)\nsmaVal = sma(close, 20)\nplot(smaVal, title=\"SMA 20\", color=#2196F3, linewidth=2, style=\"line\")\n\\`\\`\\`\n\n---\n\n## 2. plotshape()\n\nDraw a shape marker when a boolean condition is true.\n\n\\`\\`\\`\nplotshape(condition, style=, location=, color=, text=, title=)\n\\`\\`\\`\n\n| Parameter | Type | Default | Description |\n|-------------|---------|--------------|-------------|\n| condition | boolean | required | Emit shape when true |\n| style | string | \"xcross\" | Shape type (see below) |\n| location | string | \"abovebar\" | Placement on chart |\n| color | string | — | Hex color |\n| text | string | — | Label text on the shape |\n| title | string | — | Legend label |\n\n**Supported styles:**\n\\`\"xcross\"\\`, \\`\"cross\"\\`, \\`\"circle\"\\`, \\`\"triangleup\"\\`, \\`\"triangledown\"\\`, \\`\"flag\"\\`, \\`\"diamond\"\\`, \\`\"arrowup\"\\`, \\`\"arrowdown\"\\`, \\`\"square\"\\`, \\`\"label_up\"\\`, \\`\"label_down\"\\`\n\n**Supported locations:**\n\\`\"abovebar\"\\`, \\`\"belowbar\"\\`, \\`\"top\"\\`, \\`\"bottom\"\\`, \\`\"absolute\"\\`\n\n**Returns:** \\`NaN\\`\n\n**Example:**\n\\`\\`\\`forgescript\nindicator(\"Crossover Shapes\")\nfast = sma(close, 5)\nslow = sma(close, 20)\nplotshape(crossover(fast, slow), style=\"triangleup\", location=\"belowbar\", color=#00FF00, text=\"BUY\")\nplotshape(crossunder(fast, slow), style=\"triangledown\", location=\"abovebar\", color=#FF0000, text=\"SELL\")\n\\`\\`\\`\n\n---\n\n## 3. plotchar()\n\nAlias for \\`plotshape()\\` — renders character/marker shapes with identical parameters.\n\n\\`\\`\\`\nplotchar(condition, style=, location=, color=, text=, title=)\n\\`\\`\\`\n\nInternally calls the same handler as \\`plotshape()\\`.\n\n---\n\n## 4. plotarrow()\n\nDraw directional arrows based on the sign of a value.\n\n\\`\\`\\`\nplotarrow(value, colorup=, colordown=)\n\\`\\`\\`\n\n| Parameter | Type | Default | Description |\n|------------|--------|-------------|-------------|\n| value | number | required | Positive = up arrow, negative = down arrow |\n| colorup | string | \"#00FF00\" | Color for upward arrows |\n| colordown | string | \"#FF0000\" | Color for downward arrows |\n\n**Returns:** \\`value\\` (number)\n\n**Example:**\n\\`\\`\\`forgescript\nindicator(\"Momentum Arrows\")\ndelta = change(close)\nplotarrow(delta, colorup=#26a69a, colordown=#ef5350)\n\\`\\`\\`\n\n---\n\n## 5. hline()\n\nDraw a horizontal reference line at a fixed price level.\n\n\\`\\`\\`\nhline(price, title=, color=, linestyle=, linewidth=)\n\\`\\`\\`\n\n| Parameter | Type | Default | Description |\n|------------|--------|-------------|-------------|\n| price | number | required | Y-axis price level |\n| title | string | — | Line label |\n| color | string | \"#787B86\" | Hex color |\n| linestyle | string | \"dashed\" | \\`\"dashed\"\\`, \\`\"solid\"\\`, \\`\"dotted\"\\` |\n| linewidth | number | 1 | Line thickness |\n\n**Returns:** \\`price\\` (number)\n\n**Deduplication:** Only one hline per price value is stored. Duplicate prices are ignored.\n\n**Example:**\n\\`\\`\\`forgescript\nindicator(\"RSI Levels\", overlay=false)\nrsiVal = rsi(close, 14)\nhline(70, title=\"Overbought\", color=#FF0000, linestyle=\"dashed\")\nhline(30, title=\"Oversold\", color=#00FF00, linestyle=\"dashed\")\nhline(50, title=\"Midline\", color=#787B86, linestyle=\"dotted\")\nplot(rsiVal, title=\"RSI\", color=#2196F3)\n\\`\\`\\`\n\n---\n\n## 6. fill()\n\nFill the region between two plot or hline outputs.\n\n\\`\\`\\`\nfill(id1, id2, color=, title=)\n\\`\\`\\`\n\n| Parameter | Type | Default | Description |\n|-----------|--------|---------------|-------------|\n| id1 | ref | required | First plot or hline reference |\n| id2 | ref | required | Second plot or hline reference |\n| color | string | \"#00000020\" | Fill color (use alpha for transparency) |\n| title | string | — | Fill label |\n\n**Returns:** \\`NaN\\`\n\n**Example:**\n\\`\\`\\`forgescript\nindicator(\"Bollinger Band Fill\", overlay=true)\nbasis = sma(close, 20)\ndev = 2 * stdev(close, 20)\nupper = basis + dev\nlower = basis - dev\np1 = plot(upper, title=\"Upper\", color=#FF000080)\np2 = plot(lower, title=\"Lower\", color=#00FF0080)\nfill(p1, p2, color=#2196F320, title=\"BB Zone\")\nplot(basis, title=\"Basis\", color=#FF6D00)\n\\`\\`\\`\n\n---\n\n## 7. bgcolor()\n\nSet the background color of the chart for the current bar.\n\n\\`\\`\\`\nbgcolor(color)\n\\`\\`\\`\n\n| Parameter | Type | Description |\n|-----------|--------|-------------|\n| color | string | Hex color (use alpha for semi-transparency, e.g. \\`#FF000030\\`) |\n\n**Returns:** \\`NaN\\`\n\nUse \\`na\\` to skip coloring a bar:\n\\`\\`\\`forgescript\nbgcolor(close > open ? #00FF0020 : na)\n\\`\\`\\`\n\n---\n\n## 8. barcolor()\n\nOverride the OHLC candlestick color for the current bar.\n\n\\`\\`\\`\nbarcolor(color)\n\\`\\`\\`\n\n| Parameter | Type | Description |\n|-----------|--------|-------------|\n| color | string | Hex color |\n\n**Returns:** \\`NaN\\`\n\nUse \\`na\\` to keep default color:\n\\`\\`\\`forgescript\nrsiVal = rsi(close, 14)\nbarcolor(rsiVal > 70 ? #FF0000 : rsiVal < 30 ? #00FF00 : na)\n\\`\\`\\`\n\n---\n\n## 9. Output Metadata Structure\n\nWhen a ForgeScript indicator runs via \\`runFull()\\`, the result contains:\n\n| Field | Type | Description |\n|-------------|-------------------|-------------|\n| plots | IndicatorPoint[][] | One array per \\`plot()\\` call, ordered by declaration |\n| plotMetas | PlotMeta[] | Title, color, linewidth, style per plot |\n| hlines | HLineMeta[] | Horizontal line definitions |\n| fills | FillMeta[] | Fill region definitions |\n| bgcolors | BgColorEntry[] | Per-bar background colors |\n| barcolors | BarColorEntry[] | Per-bar candlestick colors |\n| shapes | ShapeEntry[] | Plotshape/plotchar/plotarrow markers |\n| overlay | boolean | From indicator() declaration |\n| title | string | From indicator() declaration |\n\nEach \\`IndicatorPoint\\` is \\`{ time: number, value: number }\\`. \\`NaN\\` values are filtered out.\n\n---\n\n## 10. Common Patterns\n\n### Multi-plot indicator\n\\`\\`\\`forgescript\nindicator(\"MACD\", overlay=false)\nmacdVal = macd(close, 12, 26, 9)\nplot(macdVal, title=\"MACD\", color=#2196F3)\nplot(__macd_signal, title=\"Signal\", color=#FF6D00)\nplot(__macd_hist, title=\"Histogram\", color=#26a69a, style=\"histogram\")\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\n\\`\\`\\`\n\n### Conditional shapes with plot\n\\`\\`\\`forgescript\nindicator(\"Overbought/Oversold\", overlay=false)\nval = rsi(close, 14)\nplot(val, title=\"RSI\", color=#2196F3)\nplotshape(val > 70, style=\"triangledown\", location=\"top\", color=#FF0000)\nplotshape(val < 30, style=\"triangleup\", location=\"bottom\", color=#00FF00)\n\\`\\`\\`\n\n### Background shading\n\\`\\`\\`forgescript\nindicator(\"Session Highlight\", overlay=true)\nisUp = close > open\nbgcolor(isUp ? #00FF0010 : #FF000010)\nplot(close, title=\"Close\")\n\\`\\`\\`\n\n## RUNTIME RULES\n\n# ForgeScript Runtime Rules & Constraints\n\nAll ForgeScript code runs inside a sandboxed tree-walking interpreter.\nThese rules define execution limits, permissions, and safety boundaries.\n\n---\n\n## 1. Execution Model\n\nForgeScript uses a **bar-by-bar execution model**:\n\n1. The entire program runs once per OHLCV bar, from top to bottom\n2. Built-in data series (\\`open\\`, \\`high\\`, \\`low\\`, \\`close\\`, \\`volume\\`, \\`time\\`) are updated before each bar\n3. Derived series (\\`hl2\\`, \\`hlc3\\`, \\`ohlc4\\`, \\`bar_index\\`) are computed automatically\n4. All statements execute sequentially — no parallelism, no async\n5. After each bar, plot values are accumulated into output arrays\n\nThere is no event loop, no callbacks, no deferred execution.\n\n---\n\n## 2. Series Ring Buffers\n\nEvery series (built-in or user-created) is backed by a **ring buffer**:\n\n- Default capacity: **1000 bars** of history\n- \\`series[n]\\` accesses n bars ago (0 = current bar)\n- Accessing beyond buffer capacity returns \\`NaN\\`\n- New values overwrite the oldest when the buffer is full\n\n---\n\n## 3. Loop Iteration Limits\n\n| Loop Type | Maximum Iterations | Error on Exceed |\n|-----------|-------------------|-----------------|\n| \\`while\\` | 10,000 | RangeError |\n| \\`for\\` | 100,000 | RangeError |\n| \\`for..in\\` | No explicit limit (bounded by array size) | — |\n\n---\n\n## 4. Sandbox Execution (Conversion Pipeline)\n\nWhen ForgeScript is generated by the AI conversion system, it runs through a sandbox:\n\n- **Test data:** 200 synthetic OHLCV bars\n- **Timeout:** 5,000ms wall-clock limit\n- **Isolation:** Fresh \\`ForgeScriptIndicator\\` instance, no shared state\n\n### Sandbox result:\n- \\`ok: true\\` — compiled and executed without errors\n- \\`ok: false\\` — compile error, runtime error, or timeout\n\n---\n\n## 5. Variable Scoping\n\n- \\`x = expr\\` — new variable, re-evaluated every bar\n- \\`var x = expr\\` — initialized once on bar 0, persists across bars\n- \\`varip x = expr\\` — initialized once, updates intra-bar on real-time ticks\n- \\`x := expr\\` — reassigns an existing variable (must be previously declared)\n- All variables are **script-scoped** — no block scoping\n- Variables declared inside \\`if\\`/\\`for\\`/\\`while\\` are visible everywhere in the script\n\n---\n\n## 6. User-Defined Functions\n\nForgeScript supports user-defined functions with Pine \\`=>\\` syntax.\n\n\\`\\`\\`forgescript\nf_zscore(src, length) =>\n m = sma(src, length)\n s = stdev(src, length)\n s != 0 ? (src - m) / s : 0.0\n\\`\\`\\`\n\n- Parameters are passed by value\n- No recursion\n- Functions are hoisted — can be called before they are defined in the source\n- All function names are script-scoped (no namespacing of user functions)\n\n---\n\n## 7. Permission Gating\n\n### request.security() & request.data()\n- \\`request.security(symbol, timeframe, expression)\\` evaluates the expression on the specified symbol and timeframe.\n- \\`request.data(datasetName, column)\\` fetches values from user-imported external datasets (CSV/JSON).\n- Both functions return \\`NaN\\` if the data is not available.\n\n---\n\n## 8. What ForgeScript Cannot Do\n\n| Category | Unavailable |\n|----------|-------------|\n| **Trading** | \\`strategy.*\\`, order placement, position management |\n| **Alerts** | \\`alertcondition\\`, \\`alert\\` |\n| **Advanced collections** | \\`matrix.*\\`, \\`map.*\\` |\n| **Modules** | \\`import\\`, \\`export\\`, \\`library\\` |\n| **OOP** | Classes, interfaces, inheritance, \\`type\\` (UDT) |\n| **Async** | Promises, callbacks, event listeners |\n| **I/O** | File read/write, network requests, database access |\n| **Logging** | \\`log.*\\`, \\`print\\`, \\`console.*\\` |\n| **Error handling** | \\`try\\`/\\`catch\\`/\\`finally\\` |\n| **MTF data** | \\`request.security()\\` (fully supported) |\n\n---\n\n## 9. What ForgeScript CAN Do (common misconceptions)\n\nThese features **are fully supported** — do not warn about them:\n\n| Feature | Notes |\n|---------|-------|\n| \\`array.*\\` (all 22+ methods) | Full array support with \\`var\\` persistence |\n| \\`table.new()\\` / \\`table.cell()\\` | Renders on-chart text panels |\n| \\`label.new()\\`, \\`line.new()\\`, \\`box.new()\\` | **Not yet implemented** — remove from converted scripts |\n| \\`str.*\\` (all 13 functions) | Including \\`startswith\\`, \\`match\\`, \\`split\\` |\n| \\`input.int/float/bool/string/source/text_area\\` | All typed input variants work |\n| \\`barstate.*\\` | \\`islast\\`, \\`isfirst\\`, \\`isconfirmed\\`, etc. |\n| \\`timeframe.*\\` | \\`period\\`, \\`multiplier\\`, \\`isintraday\\`, etc. |\n| User-defined functions (\\`f(x) => ...\\`) | Single-expression and multi-line block forms |\n| \\`for x in array\\` | Array iteration loop |\n| \\`break\\` / \\`continue\\` | Loop control statements |\n| \\`year()\\`, \\`month()\\`, \\`hour()\\`, etc. | Time extraction from Unix ms timestamps |\n| \\`color.from_gradient()\\` | Gradient color interpolation |\n| \\`plotshape()\\`, \\`plotchar()\\`, \\`plotarrow()\\` | Shape markers rendered on chart |\n| \\`hline()\\` | Horizontal reference lines rendered on chart |\n| \\`fill()\\` | Fill between hlines |\n| \\`bgcolor()\\` | Per-bar background color |\n| \\`barcolor()\\` | Per-bar candle color strip |\n\n---\n\n## 10. Indicator Declaration\n\n\\`\\`\\`forgescript\nindicator(\"Title\", overlay=false)\n\\`\\`\\`\n\n| Parameter | Type | Default | Description |\n|---------------|---------|---------|-------------|\n| title | string | required | Display name |\n| overlay | boolean | false | true = render on price pane |\n| max_bars_back | number | — | Parsed but not enforced |\n\n---\n\n## 11. Error Handling\n\nForgeScript has no try/catch. Errors propagate immediately:\n\n| Error Type | Cause | Effect |\n|------------|-------|--------|\n| Compile error | Invalid syntax | Script does not run at all |\n| ReferenceError | Undefined variable, unknown function | Bar execution halts |\n| RangeError | Loop iteration limit exceeded | Bar execution halts |\n| Timeout | Execution exceeds 5s in sandbox | Sandbox returns failure |\n\n---\n\n## 12. Determinism\n\nForgeScript execution is **deterministic**:\n- Same source + same bars = same output, always\n- \\`math.random()\\` is the only non-deterministic function\n- Plot output order matches declaration order in the source\n\n## UNSUPPORTED — DO NOT USE\n\n# ForgeScript Unsupported Features\n\nThis document catalogs every feature that ForgeScript does NOT support.\nWhen the AI encounters any of these in source code, it MUST:\n1. Report the feature in the \\`unsupportedFeatures\\` array\n2. Add a warning explaining why it cannot be converted\n3. Provide the closest approximation where possible, or omit the code\n\n---\n\n## 1. Trading & Strategy\n\nForgeScript is for **indicators only** — no trading execution.\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| \\`strategy()\\` declaration | Not supported | Use \\`indicator()\\` instead — cannot convert strategies |\n| \\`strategy.entry()\\` | Not supported | Use \\`plotshape()\\` to mark entry signals |\n| \\`strategy.exit()\\` | Not supported | Use \\`plotshape()\\` to mark exit signals |\n| \\`strategy.close()\\` | Not supported | None |\n| \\`strategy.order()\\` | Not supported | None |\n| \\`strategy.position_size\\` | Not supported | None |\n| \\`strategy.equity\\` | Not supported | None |\n| \\`strategy.profit\\` | Not supported | None |\n| Any other \\`strategy.*\\` member | Not supported | Report as unsupported |\n\n---\n\n\n\n## 3. Multi-Timeframe & External Data\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| \\`request.financial()\\` | Not supported | None |\n| \\`request.quandl()\\` | Not supported | None |\n| \\`request.dividends()\\` | Not supported | None |\n| \\`request.earnings()\\` | Not supported | None |\n| \\`request.splits()\\` | Not supported | None |\n\n---\n\n\n\n## 5. User-Defined Types (UDT)\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| Python: \\`class MyClass\\` | Not supported | Use separate variables |\n| JavaScript: \\`class MyClass\\` | Not supported | Use separate variables |\n| Enums | Not supported | Use numeric constants |\n\n## 6. Modules & Imports\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| \\`export\\` | Not supported | Not applicable |\n| \\`require()\\` | Not supported | Inline the logic |\n\n## 7. Color Extraction\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| \\`color.r(c)\\` / \\`color.g(c)\\` / \\`color.b(c)\\` | Not supported | None |\n\n---\n\n## 8. Error Handling\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| \\`finally\\` | Not supported | None |\n| \\`runtime.error()\\` | Not supported | None |\n\n## 9. I/O & External Resources\n\nEverything in this category is strictly prohibited.\n\n| Feature | Status |\n|---------|--------|\n| File reading/writing | Not supported |\n| HTTP requests | Not supported |\n| Database queries | Not supported |\n| WebSocket connections | Not supported |\n| Console output / logging | Not supported |\n| Environment variables | Not supported |\n| Process execution | Not supported |\n\n---\n\n## 10. Approximation Guidelines\n\nWhen the source code uses an unsupported feature, follow these rules:\n\n1. **If a close approximation exists** (e.g., \\`alertcondition()\\` → \\`plotshape()\\`): Use the approximation AND warn the user about semantic differences\n2. **If the feature is cosmetic** (e.g., \\`log.info()\\`, \\`print()\\`): Remove it silently with an info-level warning\n3. **If the feature is functional** (e.g., \\`strategy.entry()\\`, \\`matrix.*\\`): Report it as unsupported and explain what was lost\n4. **If the feature is critical to the script's purpose** (e.g., strategy execution in a strategy script): Lower confidence to LOW and explain that the conversion is incomplete\n5. **Never invent functions** that don't exist in ForgeScript — this causes hallucination validation failures\n`;\n","/**\n * Agent System Prompt Builder\n *\n * Constructs the complete system prompt for the Anthropic Claude API,\n * including role definition, core rules, ForgeScript reference, and chart context.\n */\n\nimport type { ChartContextSnapshot } from '@forgecharts/types';\nimport { FORGESCRIPT_REFERENCE } from './knowledge';\n\n/**\n * Builds the complete system prompt for the agent given the current chart context.\n * Includes role definition, operational rules, ForgeScript reference, and context snapshot.\n */\nexport function buildSystemPrompt(chartContext: ChartContextSnapshot): string {\n const contextSection = formatChartContext(chartContext);\n\n return `# ForgeCharts AI Assistant\n\nYou are the ForgeCharts AI Assistant, an expert in technical analysis, market microstructure, and custom indicator development using ForgeScript. You help traders and analysts understand charts, develop indicators, and manage their trading workflows.\n\n## Core Operational Rules\n\n### Drawing Rule (CRITICAL)\nWhen asked to draw support/resistance, trend lines, or any price-based annotation:\n1. ALWAYS call \\`data_get_bars\\` FIRST to fetch recent price data\n2. Find the exact high/low/close prices from the returned bars\n3. Use precise price levels from the data — NEVER estimate or guess prices\n4. Only then call \\`drawing_add\\` with the exact timestamp and price coordinates\n\n**Why:** Eyeballing prices leads to inaccurate analysis. Real price levels matter.\n\n### Built-in Indicator Preference (CRITICAL)\nWhen a user asks for a standard indicator (Bollinger Bands, EMA, SMA, RSI, MACD, Stochastic, ATR, OBV, Volume):\n1. **ALWAYS use \\`indicator_add\\`** with the built-in type — NEVER create a ForgeScript for these\n2. Built-in types: \\`sma\\`, \\`ema\\`, \\`wma\\`, \\`rsi\\`, \\`macd\\`, \\`bbands\\`, \\`stochastic\\`, \\`atr\\`, \\`obv\\`, \\`volume\\`\n3. Built-in indicators have proper overlay placement, configurable settings dialogs, and optimised rendering\n\n**Built-in indicator defaults:**\n| Type | Overlay | Default Params |\n|------|---------|---------------|\n| \\`sma\\` | yes | period: 20 |\n| \\`ema\\` | yes | period: 20 |\n| \\`wma\\` | yes | period: 20 |\n| \\`bbands\\` | yes | period: 20, maType: \"sma\", source: \"close\", multiplier: 2, offset: 0 |\n| \\`rsi\\` | no | period: 14 |\n| \\`macd\\` | no | fast: 12, slow: 26, signal: 9 |\n| \\`stochastic\\` | no | kPeriod: 14, dPeriod: 3, smooth: 3 |\n| \\`atr\\` | no | period: 14 |\n| \\`obv\\` | no | (none) |\n| \\`volume\\` | no | (none) |\n\nOnly use ForgeScript (\\`script_create\\` / \\`script_compile_attach\\`) for **custom** indicators that are NOT available as built-in types — for example, custom oscillators, multi-factor composites, or proprietary calculations.\n\n### ForgeScript Rule (CRITICAL)\nWhen developing or modifying ForgeScript indicators:\n1. ALWAYS call \\`script_validate\\` first on your source code\n2. Read the error message carefully if validation fails\n3. Fix the error (check syntax, variable declarations, function names)\n4. Call \\`script_validate\\` again until it passes (status = \"clean\")\n5. Only then proceed to \\`script_compile_attach\\`\n\n**Why:** Validation catches logic errors before wasting time compiling broken code.\n\n### ForgeScript indicator() Syntax (CRITICAL)\nEvery script MUST start with \\`indicator()\\` using a **string literal** as the first argument:\n\\`\\`\\`\nindicator(\"My Indicator Title\", overlay=true)\n\\`\\`\\`\n- The title MUST be a **string literal** in double quotes — NOT a variable or identifier\n- WRONG: \\`indicator(title)\\`, \\`indicator('title')\\`, \\`indicator(myTitle)\\`\n- CORRECT: \\`indicator(\"MACD Custom\", overlay=false)\\`\n\n### ForgeScript Configurable Inputs & Style (CRITICAL)\nEvery ForgeScript indicator MUST expose **all tuneable values** as \\`input()\\` declarations so users can adjust them via the settings dialog (gear icon). This includes:\n\n1. **Numeric parameters** — use \\`input()\\`, \\`input.int()\\`, or \\`input.float()\\` with descriptive \\`title\\` and sensible \\`minval\\`/\\`step\\`:\n \\`\\`\\`\n length = input.int(14, title=\"Length\", minval=1)\n mult = input.float(2.0, title=\"Multiplier\", step=0.1, minval=0.1)\n \\`\\`\\`\n2. **Source fields** — use \\`input.source()\\` or \\`input(close, title=\"Source\")\\`:\n \\`\\`\\`\n src = input(close, title=\"Source\")\n \\`\\`\\`\n3. **Line colours** — use \\`input.color()\\` and pass the result to \\`plot()\\` via the \\`color\\` argument:\n \\`\\`\\`\n lineCol = input.color(#2196f3, title=\"Line Color\")\n plot(value, title=\"Signal\", color=lineCol, linewidth=2)\n \\`\\`\\`\n4. **Boolean toggles** — use \\`input.bool()\\` for optional features:\n \\`\\`\\`\n showBand = input.bool(true, title=\"Show Fill\")\n \\`\\`\\`\n\n**Rules:**\n- NEVER hard-code a magic number (period, length, multiplier, threshold) — always wrap it in \\`input()\\`\n- NEVER hard-code a plot colour — always use \\`input.color()\\` so the user can customise it from settings\n- Give every input a clear, user-friendly \\`title\\`\n- Group related inputs together (lengths first, then style, then toggles)\n- Use \\`input.int()\\` for whole-number params and \\`input.float()\\` for decimal params with appropriate \\`step\\`\n\n**Example — correct pattern:**\n\\`\\`\\`\nindicator(\"Custom RSI\", overlay=false)\nlength = input.int(14, title=\"RSI Length\", minval=1)\nupper = input.int(70, title=\"Overbought Level\", minval=50, maxval=100)\nlower = input.int(30, title=\"Oversold Level\", minval=0, maxval=50)\nrsiColor = input.color(#7b1fa2, title=\"RSI Color\")\nobColor = input.color(#ef5350, title=\"Overbought Line Color\")\nosColor = input.color(#26a69a, title=\"Oversold Line Color\")\n\nrsiVal = ta.rsi(close, length)\nplot(rsiVal, title=\"RSI\", color=rsiColor, linewidth=2)\nhline(upper, title=\"Overbought\", color=obColor, linestyle=\"dashed\")\nhline(lower, title=\"Oversold\", color=osColor, linestyle=\"dashed\")\n\\`\\`\\`\n\n**Why:** Without \\`input()\\` calls, the indicator has no settings for the user to adjust — it becomes a black box with no configurability.\n\n### Updating an Existing Script (CRITICAL)\nWhen the user asks you to modify a script that is already running on the chart:\n1. Call \\`script_update_source\\` with the new code\n2. Call \\`script_validate\\` to verify the new code\n3. Call \\`script_compile_attach\\` — this will **automatically detach the old instance** before attaching the updated version\nDo NOT call \\`script_create\\` to make a second copy. Do NOT manually call \\`script_detach\\` — \\`script_compile_attach\\` handles it.\n\n### Script Publishing Workflow (CRITICAL)\nAfter creating and compiling a ForgeScript indicator, ALWAYS complete these additional steps:\n\n1. **Documentation** — Call \\`script_docs_write\\` with Markdown content that includes:\n - A one-line summary of what the indicator does\n - A description of how it works (the calculation logic)\n - A parameter table listing every \\`input()\\` with its name, type, default, and description\n - Usage tips and examples\n **Why:** Scripts without documentation are unusable to other users and hard to maintain.\n\n2. **Datasets** — If the indicator needs external data (e.g., earnings dates, custom signals, economic data), call \\`script_dataset_create\\` to define the schema. Each dataset:\n - Has an implicit first column: \\`time\\` (timestamptz)\n - Must use lowercase snake_case names\n - Column types: \\`number\\`, \\`integer\\`, \\`text\\`, \\`boolean\\`, \\`date\\`, \\`timestamp\\`, \\`percentage\\`, \\`price\\`\n The user can later import CSV/JSON data into the dataset to populate it.\n **Only create datasets when the indicator genuinely requires external data** — most indicators operate on built-in OHLCV series and do not need a dataset.\n\n3. **Visibility** — Ask the user how they want to share the script, then call \\`script_set_visibility\\`:\n - \\`private\\` — only the owner can see/use it (default)\n - \\`public\\` — any user can see and use it for free\n - \\`for_sale\\` — listed on the marketplace at a set price (minimum $1.00). Set \\`preview_pct\\` (0-100) to control how much source code non-purchasers can see.\n **Always ask before setting visibility** — never assume the user wants to publish or sell.\n\n**Complete script creation flow:**\n\\`\\`\\`\nscript_create → script_validate → script_compile_attach\n → script_docs_write (always)\n → script_dataset_create (only if needed)\n → script_set_visibility (ask user first)\n\\`\\`\\`\n\n### Removing Indicators (IMPORTANT)\nTo remove an indicator from the chart, call \\`indicator_remove\\` with the \\`indicatorId\\` parameter. You can get indicator IDs from \\`indicator_list\\`.\n\n### UI Automation (IMPORTANT)\nThe ForgeCharts platform responds to your tool calls by automatically showing the relevant UI panel. You DO have the ability to drive the interface:\n\n- Calling \\`watchlist_get\\` or \\`watchlist_add\\` → **opens the Watchlist drawer**\n- Calling \\`indicator_list\\` or \\`indicator_add\\` → **opens then auto-closes the Indicators dialog**\n- Calling \\`trading_get_positions\\` → **opens the Positions tab** in the trading panel\n- Calling \\`trading_get_orders\\` → **opens the Orders tab** in the trading panel\n- Calling \\`trading_get_fills\\` → **opens the Fills tab** in the trading panel\n- Calling \\`script_create\\` or \\`script_update_source\\` → **opens the Script editor** and types the code live\n- Calling \\`chart_set_timeframe\\` → **switches the chart timeframe**\n- Calling \\`chart_set_symbol\\` → **changes the chart symbol**\n\nWhen a user asks to \"show me the watchlist\", \"open the indicators\", \"show positions\", etc. — call the appropriate tool. The UI will respond automatically.\n\n### Futures Contract Rule (CRITICAL)\nWhen a user asks to \"open a contract\", \"switch to ES\", \"pull up crude\", or any request involving a futures symbol:\n1. Call \\`contract_get_info\\` to determine contract metadata for the symbol\n2. If the symbol is a futures product, ALWAYS ask the user to choose:\n - **Continuous contract** (e.g., CME:ES1!) — automatically rolls to the front month, provides seamless historical data\n - **Specific monthly contract** (e.g., CME:ESU2026) — the exact current front-month contract with real expiry\n3. Present both options clearly, including the exact contract name and month\n4. Only call \\`chart_set_symbol\\` AFTER the user has chosen\n5. Always include the exchange prefix for futures (e.g., \"CME:ES1!\", not just \"ES1!\")\n\n**Example response:**\n\"ES is currently in the **September 2026 (ESU2026)** contract. Would you like me to open:\n- **CME:ES1!** — the continuous contract (auto-rolls, seamless history)\n- **CME:ESU2026** — the specific September 2026 contract\n\nWhich do you prefer?\"\n\n**Why:** Traders need to know exactly which contract they're viewing. Continuous contracts stitch history across rolls, while specific contracts show the actual tradeable instrument with a real expiry date.\n\nThe chart context includes \\`contractInfo\\` when the current symbol is a futures product — use it to report the active contract without needing an extra tool call.\n\n### Trading Rule (CRITICAL)\nYou have READ-ONLY access to trading data. You CANNOT:\n- Place new orders\n- Modify existing orders\n- Cancel orders\n- Close or exit positions\n- Execute any trading action\n\nIf asked to place, modify, or cancel an order:\n1. Decline politely\n2. Explain the limitation\n3. Redirect to manual order entry in the UI\n4. Optionally help analyze market conditions for their decision\n\n**Example response:** \"I can't place orders, but I can help you analyze the chart. Let me fetch bars around [level] to show you the support/resistance setup...\"\n\n### Tone & Communication\n- **Concise:** Skip basic explanations unless directly asked \"explain this to me\"\n- **Professional:** Use proper terminology (e.g., \"confluence\", \"liquidity void\", not \"seems bullish\")\n- **Action-oriented:** Prefer \"Call X to achieve Y\" over lengthy theory\n- **Context-aware:** Reference the current chart state (symbol, timeframe, indicators)\n\n## Current Chart Context\n\n${contextSection}\n\n## ForgeScript Language Reference\n\n${FORGESCRIPT_REFERENCE}\n\n---\n\n**End of System Prompt**\n`;\n}\n\n/**\n * Formats the chart context snapshot into a readable summary section.\n */\nfunction formatChartContext(ctx: ChartContextSnapshot): string {\n const indicatorList =\n ctx.indicators.length > 0\n ? ctx.indicators.map(ind => ` - ${ind.name} (${ind.visible ? 'visible' : 'hidden'})`).join('\\n')\n : ' (none)';\n\n const drawingList =\n ctx.drawings.length > 0\n ? ctx.drawings.map(drw => ` - ${drw.type} [${drw.id}]`).join('\\n')\n : ' (none)';\n\n const barSummary =\n ctx.recentBars.length > 0\n ? (() => {\n const closes = ctx.recentBars.map(b => b.close);\n const high = Math.max(...closes);\n const low = Math.min(...closes);\n const latest = ctx.recentBars[ctx.recentBars.length - 1]!;\n return `${ctx.recentBars.length} bars loaded; latest close: ${latest.close}, range: ${low} to ${high}`;\n })()\n : '(no bars loaded)';\n\n const tradingStatus = ctx.tradingConnected\n ? `Connected, ${ctx.openPositionCount} open position(s)`\n : 'Not connected';\n\n const contractLine = ctx.contractInfo\n ? `\\n- Contract Type: **${ctx.contractInfo.isContinuous ? 'Continuous' : 'Specific Monthly'}** (product: ${ctx.contractInfo.product}, exchange: ${ctx.contractInfo.exchange})\\n- Front-Month Contract: **${ctx.contractInfo.frontMonthContract}**\\n- Continuous Symbol: **${ctx.contractInfo.continuousSymbol}**`\n : '';\n\n return `### Symbol & Viewport\n- Symbol: **${ctx.symbol}**\n- Timeframe: **${ctx.timeframe}**\n- Chart Type: **${ctx.chartType}**${contractLine}\n- Visible Range: ${ctx.visibleRange.from} to ${ctx.visibleRange.to} (bars)\n\n### Recent Data\n- ${barSummary}\n\n### Indicators\n${indicatorList}\n\n### Drawings\n${drawingList}\n\n### Trading Status\n- ${tradingStatus}\n`;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * ForgeScript Language & Runtime Knowledge Base
3
+ *
4
+ * This module exports consolidated ForgeScript documentation for use in
5
+ * Claude system prompts. Two exports:
6
+ * - FORGESCRIPT_REFERENCE: 135-line condensed reference for quick lookup
7
+ * - FORGESCRIPT_KNOWLEDGE: Full consolidated knowledge base for detailed instructions
8
+ */
9
+ export declare const FORGESCRIPT_REFERENCE = "## ForgeScript Language Reference\n\nForgeScript is a domain-specific language for financial technical indicators.\nIt uses a bar-by-bar execution model with persistent series state.\n\n### Data Series (always available)\nopen, high, low, close, volume, time, hl2, hlc3, ohlc4, bar_index\n\n### Bar State\nbarstate.islast, barstate.isfirst, barstate.isconfirmed, barstate.isnew,\nbarstate.isrealtime (always false), barstate.ishistory (always true)\n\n### Syntax\n\nCRITICAL \u2014 Assignment vs Reassignment:\n- First assignment MUST use = (equals sign): length = input(14)\n- Reassignment of an existing variable uses := (colon-equals): length := length + 1\n- NEVER use := to declare a variable for the first time \u2014 this is a runtime error\n- var (init-once per symbol): var x = 0 (uses = for the initial declaration)\n- varip (init-once per session): varip x = 0 (uses = for the initial declaration)\n- if/else (using indented blocks)\n- for i = start to end [by step] (indented block)\n- while condition (indented block)\n- Ternary: condition ? then : else\n- Index lookback: series[n] \u2014 access n bars ago\n- Named arguments: plot(val, title=\"EMA\", color=#FF0000)\n\n### Built-in Functions\n\n#### Technical Analysis (flat or ta.* namespace)\nsma, ema, wma, rma, rsi, stdev, atr, highest, lowest, change, mom,\ncrossover, crossunder, cross, macd, bb, stoch, obv, correlation,\ndev, variance, cum, sum, valuewhen, barssince, pivothigh, pivotlow,\ntr, swma, vwma, rising, falling\n\n#### Math (flat or math.* namespace)\nabs, max, min, round, floor, ceil, sqrt, log, exp, pow, sign,\nsin, cos, tan, asin, acos, atan, todegrees, toradians, avg, sum, random, log10\n\n#### Color\n17 named constants: color.red, color.green, color.blue, color.white, color.black, color.yellow,\ncolor.orange, color.purple, color.fuchsia, color.lime, color.maroon, color.navy, color.olive,\ncolor.silver, color.teal, color.aqua, color.gray\ncolor.new(baseColor, transparency) \u2014 transparency 0-100 (100=fully transparent)\ncolor.rgb(r, g, b, transparency?) \u2014 values 0-255 for r/g/b\ncolor.from_gradient(value, bottom_value, top_value, bottom_color, top_color) \u2014 linear interpolation\nHex literals: #RRGGBB or #RRGGBBAA\n\n#### String\nstr.tostring(value), str.tonumber(value), str.format(template, args...),\nstr.length(s), str.trim(s), str.contains(s, sub), str.startswith(s, prefix),\nstr.substring(s, start, end), str.replace_all(s, target, replacement),\nstr.upper(s), str.lower(s), str.split(s, separator) \u2192 returns an array,\nstr.match(s, regex) \u2192 returns matched string or \"\"\n\n#### Arrays\narray.new_float(size, initial_value), array.new_int(size, initial_value),\narray.new_string(size, initial_value), array.new_bool(size, initial_value),\narray.from(val1, val2, ...) \u2014 create array from values\narray.size(arr), array.get(arr, index), array.set(arr, index, value),\narray.push(arr, value), array.pop(arr), array.remove(arr, index),\narray.clear(arr), array.includes(arr, value), array.indexof(arr, value),\narray.slice(arr, start, end), array.join(arr, separator),\narray.sort(arr), array.reverse(arr),\narray.avg(arr), array.sum(arr), array.min(arr), array.max(arr)\n\n#### Tables (screen-positioned text panels)\ntable.new(position, columns, rows, bgcolor=, border_color=, border_width=, frame_color=, frame_width=) \u2014 returns table id\ntable.cell(table_id, column, row, text, text_color=, bgcolor=, text_size=, text_halign=, text_valign=)\ntable.clear(table_id, first_col, first_row, last_col?, last_row?) \u2014 remove one cell or a range of cells\ntable.delete(table_id) \u2014 remove the entire table\nPosition values: \"top_right\", \"top_left\", \"bottom_right\", \"bottom_left\", etc.\nAlignment: text.align_left \u2192 \"left\", text.align_center \u2192 \"center\", text.align_right \u2192 \"right\"\n text.align_top \u2192 \"top\", text.align_bottom \u2192 \"bottom\"\n\n#### User-defined Functions\nname(param1, param2) => expression\nname(param1, param2) =>\n statement1\n statement2\n result_expression\n\n#### Output\nplot(value, title=, color=, linewidth=, style=)\nplotshape(condition, style=, location=, color=, text=, title=)\nplotchar, plotarrow, hline(price), fill, bgcolor(color), barcolor(color)\n\n#### Pine Enum Constants (pass through as strings)\nshape.* \u2192 \"circle\", \"triangleup\", \"arrowup\", etc.\nlocation.* \u2192 \"abovebar\", \"belowbar\", \"top\", \"bottom\", \"absolute\"\nplot.style_* \u2192 \"line\", \"histogram\", \"area\", \"columns\"\nposition.* \u2192 \"top_right\", \"top_left\", \"bottom_right\", \"bottom_left\", etc.\nsize.* \u2192 \"auto\", \"tiny\", \"small\", \"normal\", \"large\", \"huge\"\ntext.align_* \u2192 \"left\", \"center\", \"right\", \"top\", \"bottom\"\n\n#### Input Parameters (all variants fully supported \u2014 return the default value at runtime)\ninput(defval, title=)\ninput.int(defval, title?, minval?, maxval?, step?)\ninput.float(defval, title?, minval?, maxval?, step?)\ninput.bool(defval, title?)\ninput.string(defval, title?, options?)\ninput.color(defval, title?)\ninput.source(defval, title?)\ninput.text_area(defval, title?)\nExtra named args like tooltip=, group=, inline=, confirm= are accepted and silently ignored.\nOptions lists in input.string/input.int are accepted and silently ignored (only the default value matters).\n\n#### Utility\nna, nz(value, replacement)\n\n### NOT SUPPORTED (do NOT use these)\n- strategy.*, alertcondition, alert\n- label, line, box, matrix\n- import/export/module/library\n- Classes or OOP constructs\n- Async/await, promises, callbacks\n- File I/O, network requests\n- request.security (stub only \u2014 returns 0)\n";
10
+ export declare const FORGESCRIPT_KNOWLEDGE = "## FORGESCRIPT LANGUAGE\n\n# ForgeScript Language Specification\n\n> Canonical reference for the ForgeScript scripting language.\n> ForgeScript is a domain-specific language for financial technical indicators\n> running inside ForgeCharts.\n\n## 1. Overview\n\nForgeScript is a bar-by-bar interpreted scripting language designed for writing\ncustom technical indicators. Its syntax is intentionally Pine Script v5-compatible\nat the expression and built-in level so that users familiar with Pine can write\nForgeScript directly.\n\n## 2. Execution Model\n\n```\n[bar 0] [bar 1] [bar 2] \u2026 [bar N-1] [forming bar]\n \u2502 \u2502 \u2502 \u2502 \u2502\nForgeScriptRuntime.execBar(bar, index)\n \u2502\n \u251C\u2500 Updates built-in series: open, high, low, close, volume, time, hl2, hlc3, ohlc4, bar_index\n \u251C\u2500 Executes user code top-to-bottom\n \u2514\u2500 Collects plot() / plotshape() / hline() / bgcolor() / barcolor() calls \u2192 output frame\n```\n\n- The script is called **once per bar** in historical order\n- Then **once per real-time update** (forming bar)\n- All numeric values are IEEE 754 double-precision floats\n\n## 3. Series Behavior\n\nA **series** is a time-indexed sequence of values \u2014 one value per bar. All\nbuilt-in data (`open`, `high`, `low`, `close`, `volume`, `time`) are series.\nUser-assigned variables also become series implicitly.\n\nSeries values are stored in ring buffers (default capacity: 1000 bars). Access\nprevious values with lookback syntax:\n\n```\nclose[0] // current bar's close (same as just `close`)\nclose[1] // previous bar's close\nclose[n] // n bars ago\n```\n\nLookback index must be a non-negative integer. `close[-1]` is invalid.\n\n## 4. Variable Declarations\n\n### Simple assignment (re-evaluated every bar)\n```\nlength = 14\nsrc = close\nvalue = ta.sma(close, length)\n```\n\n### `var` \u2014 persistent across bars (init once on bar 0)\n```\nvar counter = 0\ncounter := counter + 1 // increments every bar\n```\n\n### `varip` \u2014 persistent, updated intra-bar\n```\nvarip tick_count = 0\ntick_count := tick_count + 1\n```\n\n### Reassignment with `:=`\n```\nx = 10 // initial assignment\nx := x + 1 // reassignment (variable must already exist)\n```\n\n**Rule**: `=` creates a new variable. `:=` modifies an existing one. Using `:=`\non an undeclared variable is a runtime error.\n\n## 5. Syntax Rules\n\n### Comments\n```\n// This is a line comment\nx = 10 // inline comment\n```\n\n### Code blocks (indentation-based)\n```\nif condition\n x = 10\n y = 20\nelse\n x = 0\n```\n\n### Operators\n\n| Category | Operators |\n|---|---|\n| Arithmetic | `+`, `-`, `*`, `/`, `%` |\n| Comparison | `<`, `>`, `<=`, `>=`, `==`, `!=` |\n| Logical | `and`, `or`, `not` |\n| Ternary | `condition ? then_value : else_value` |\n| Assignment | `=` (declare), `:=` (reassign) |\n\n### Operator Precedence (low \u2192 high)\n1. Ternary `? :`\n2. `or`\n3. `and`\n4. `not`\n5. Comparison `< > <= >= == !=`\n6. Addition `+ -`\n7. Multiplication `* / %`\n8. Unary `-`\n9. Primary (literals, identifiers, calls, index)\n\n### Literal Types\n| Type | Examples |\n|---|---|\n| Number | `42`, `3.14`, `.5` |\n| String | `\"hello\"`, `'world'` |\n| Boolean | `true`, `false` |\n| Color | `#FF0000`, `#FF000080` (with alpha) |\n| NA | `na` |\n\n## 6. Control Flow\n\n### If / Else\n```\nif ta.crossover(fast_ma, slow_ma)\n signal = 1\nelse if ta.crossunder(fast_ma, slow_ma)\n signal = -1\nelse\n signal = 0\n```\n\n### Ternary Expression\n```\ncolor_val = close > open ? color.green : color.red\n```\n\n### For Loop (numeric range)\n```\nsum = 0.0\nfor i = 0 to length - 1\n sum := sum + close[i]\n\n// With step\nfor i = 0 to 100 by 5\n // body\n```\n\n### For Loop (array iteration)\n```\nvar prices = array.new_float(0)\narray.push(prices, close)\nfor val in prices\n // val is each element\n```\n\n### While Loop\n```\nvar count = 0\nwhile count < 10\n count := count + 1\n```\n\n### Break and Continue\n```\nfor i = 0 to 100\n if i == 50\n break // exit loop\n if i % 2 == 0\n continue // skip to next iteration\n```\n\n## 7. User-Defined Functions\n\nForgeScript supports user-defined functions with Pine-style `=>` syntax.\n\n### Single-expression function\n```\nf_double(x) => x * 2\nresult = f_double(close)\n```\n\n### Multi-line function body\n```\nf_clamp(val, lo, hi) =>\n clamped = val\n if val < lo\n clamped := lo\n if val > hi\n clamped := hi\n clamped\n```\n\n### Functions with multiple parameters\n```\nf_zscore(src, length) =>\n m = sma(src, length)\n s = stdev(src, length)\n s != 0 ? (src - m) / s : 0.0\n\nzs = f_zscore(close, 20)\nplot(zs, title=\"Z-Score\")\n```\n\n**Notes:**\n- Parameters are passed by value\n- Functions can call other functions (no recursion)\n- Functions are hoisted \u2014 can be defined after use\n- The last expression in a multi-line body is the return value\n\n## 8. Declarations\n\n### indicator()\nEvery indicator script MUST begin with:\n```\nindicator(\"Title\", overlay=false, max_bars_back=500)\n```\n\nParameters:\n- `title` (string, required) \u2014 display name\n- `overlay` (bool, optional) \u2014 `true` = draw on price pane, `false` = separate pane\n- `shorttitle` (string, optional) \u2014 abbreviated name\n- `max_bars_back` (int, optional) \u2014 maximum lookback depth\n\n## 9. Special Values\n\n| Value | Description |\n|---|---|\n| `na` | Missing/undefined value (equivalent to `NaN`) |\n| `na(x)` | Returns `true` if `x` is `na` |\n| `nz(x)` | Returns `0` if `x` is `na`, otherwise `x` |\n| `nz(x, y)` | Returns `y` if `x` is `na`, otherwise `x` |\n\n## 10. Namespaces\n\n| Namespace | Purpose |\n|---|---|\n| `ta.*` | Technical analysis functions |\n| `math.*` | Mathematical functions and constants |\n| `color.*` | Color constants and constructors |\n| `str.*` | String utility functions |\n| `array.*` | Array (mutable collection) functions |\n| `table.*` | On-chart table rendering |\n| `input.*` | Typed user parameter declarations |\n| `syminfo.*` | Symbol metadata (read-only) |\n| `barstate.*` | Bar state flags (islast, isfirst, etc.) |\n| `timeframe.*` | Timeframe properties |\n| `request.*` | External data and MTF data |\n\nFunctions in `ta.*` and `math.*` can also be called without the namespace prefix:\n```\nsma(close, 14) // same as ta.sma(close, 14)\nabs(-5) // same as math.abs(-5)\n```\n\n## 11. Time Functions\n\nExtract components from a Unix millisecond timestamp (or current bar time if no arg):\n\n```\nyr = year(time) // 4-digit year, e.g. 2024\nmo = month(time) // 1\u201312\ndom = dayofmonth(time) // 1\u201331\ndow = dayofweek(time) // 1=Sunday \u2026 7=Saturday\nhr = hour(time) // 0\u201323\nmn = minute(time) // 0\u201359\nsc = second(time) // 0\u201359\n\n// Construct a timestamp\nts = timestamp(2024, 1, 15, 9, 30, 0)\n```\n\n## 12. Keywords\n\nReserved words (cannot be used as variable names):\n- `true`, `false`, `na`\n- `and`, `or`, `not`\n- `var`, `varip`\n- `if`, `else`, `for`, `while`, `in`, `to`, `by`\n- `break`, `continue`\n- `indicator`, `input`, `plot`\n\n## BUILT-IN FUNCTIONS\n\n# ForgeScript Built-in Functions Reference\n\n> Complete catalog of all built-in functions, namespaces, and constants\n> available in ForgeScript. Any function NOT listed here is UNSUPPORTED.\n\n## 1. Technical Analysis \u2014 `ta.*` Namespace\n\nAll TA functions accept series data. Can be called with or without `ta.` prefix.\n\n### Moving Averages\n\n| Function | Signature | Description |\n|---|---|---|\n| `ta.sma` / `sma` | `(source, length) \u2192 float` | Simple Moving Average |\n| `ta.ema` / `ema` | `(source, length) \u2192 float` | Exponential Moving Average |\n| `ta.wma` / `wma` | `(source, length) \u2192 float` | Weighted Moving Average |\n| `ta.rma` / `rma` | `(source, length) \u2192 float` | Wilder's Moving Average |\n| `ta.swma` / `swma` | `(source) \u2192 float` | Symmetrically Weighted Moving Average |\n| `ta.vwma` / `vwma` | `(source, length) \u2192 float` | Volume-Weighted Moving Average |\n\n### Oscillators and Indicators\n\n| Function | Signature | Description |\n|---|---|---|\n| `ta.rsi` / `rsi` | `(source, length) \u2192 float` | Relative Strength Index [0, 100] |\n| `ta.macd` / `macd` | `(source, fast, slow, signal) \u2192 float` | Returns MACD line; stores `__macd_signal`, `__macd_hist` |\n| `ta.stoch` / `stoch` | `(close, high, low, length) \u2192 float` | Stochastic %K |\n| `ta.obv` / `obv` | `(close, volume) \u2192 float` | On-Balance Volume |\n\n### Bands and Volatility\n\n| Function | Signature | Description |\n|---|---|---|\n| `ta.bb` / `bb` | `(source, length, mult?) \u2192 float` | Bollinger Bands \u2014 returns middle; stores `__bb_upper`, `__bb_lower` |\n| `ta.atr` / `atr` | `(length) \u2192 float` | Average True Range |\n| `ta.tr` / `tr` | `() \u2192 float` | True Range (single bar) |\n| `ta.stdev` / `stdev` | `(source, length) \u2192 float` | Standard Deviation |\n| `ta.dev` / `dev` | `(source, length) \u2192 float` | Mean Absolute Deviation |\n| `ta.variance` / `variance` | `(source, length) \u2192 float` | Variance |\n\n### Crossover and Signal Detection\n\n| Function | Signature | Description |\n|---|---|---|\n| `ta.crossover` / `crossover` | `(a, b) \u2192 bool` | True when `a` crosses above `b` |\n| `ta.crossunder` / `crossunder` | `(a, b) \u2192 bool` | True when `a` crosses below `b` |\n| `ta.cross` / `cross` | `(a, b) \u2192 bool` | True on any cross |\n| `ta.rising` / `rising` | `(source, length) \u2192 bool` | True if source rose for `length` bars |\n| `ta.falling` / `falling` | `(source, length) \u2192 bool` | True if source fell for `length` bars |\n\n### Rolling Aggregates\n\n| Function | Signature | Description |\n|---|---|---|\n| `ta.highest` / `highest` | `(source, length) \u2192 float` | Rolling maximum |\n| `ta.lowest` / `lowest` | `(source, length) \u2192 float` | Rolling minimum |\n| `ta.sum` / `sum` | `(source, length) \u2192 float` | Rolling sum |\n| `ta.cum` / `cum` | `(source) \u2192 float` | Cumulative sum from bar 0 |\n| `ta.correlation` / `correlation` | `(src1, src2, length) \u2192 float` | Pearson correlation |\n\n### Change and Momentum\n\n| Function | Signature | Description |\n|---|---|---|\n| `ta.change` / `change` | `(source, length?) \u2192 float` | `source - source[length]` (default length=1) |\n| `ta.mom` / `mom` | `(source, length) \u2192 float` | Momentum = change over N bars |\n\n### Lookback Utilities\n\n| Function | Signature | Description |\n|---|---|---|\n| `ta.valuewhen` / `valuewhen` | `(condition, source, occurrence) \u2192 float` | Value at Nth true condition |\n| `ta.barssince` / `barssince` | `(condition) \u2192 int` | Bars since condition was last true |\n| `ta.pivothigh` / `pivothigh` | `(source, leftbars, rightbars) \u2192 float|na` | Pivot high detection |\n| `ta.pivotlow` / `pivotlow` | `(source, leftbars, rightbars) \u2192 float|na` | Pivot low detection |\n\n---\n\n## 2. Math \u2014 `math.*` Namespace\n\nCan be called with or without `math.` prefix.\n\n| Function | Signature | Description |\n|---|---|---|\n| `math.abs` / `abs` | `(x) \u2192 float` | Absolute value |\n| `math.max` / `max` | `(...args) \u2192 float` | Maximum of arguments |\n| `math.min` / `min` | `(...args) \u2192 float` | Minimum of arguments |\n| `math.round` / `round` | `(x) \u2192 float` | Round to nearest integer |\n| `math.floor` / `floor` | `(x) \u2192 float` | Round down |\n| `math.ceil` / `ceil` | `(x) \u2192 float` | Round up |\n| `math.sqrt` / `sqrt` | `(x) \u2192 float` | Square root |\n| `math.log` / `log` | `(x) \u2192 float` | Natural logarithm |\n| `math.log10` / `log10` | `(x) \u2192 float` | Base-10 logarithm |\n| `math.exp` / `exp` | `(x) \u2192 float` | e^x |\n| `math.pow` / `pow` | `(base, exp) \u2192 float` | Exponentiation |\n| `math.sign` / `sign` | `(x) \u2192 float` | Sign: -1, 0, or 1 |\n| `math.sin` / `sin` | `(x) \u2192 float` | Sine (radians) |\n| `math.cos` / `cos` | `(x) \u2192 float` | Cosine (radians) |\n| `math.tan` / `tan` | `(x) \u2192 float` | Tangent (radians) |\n| `math.asin` / `asin` | `(x) \u2192 float` | Arc sine |\n| `math.acos` / `acos` | `(x) \u2192 float` | Arc cosine |\n| `math.atan` / `atan` | `(x) \u2192 float` | Arc tangent |\n| `math.todegrees` / `todegrees` | `(radians) \u2192 float` | Radians to degrees |\n| `math.toradians` / `toradians` | `(degrees) \u2192 float` | Degrees to radians |\n| `math.avg` / `avg` | `(...args) \u2192 float` | Average of arguments |\n| `math.random` / `random` | `() \u2192 float` | Random number [0, 1) |\n\n### Constants\n\n| Constant | Value |\n|---|---|\n| `math.pi` | 3.14159265358979 |\n| `math.e` | 2.71828182845905 |\n\n---\n\n## 3. Color \u2014 `color.*` Namespace\n\n### Named Color Constants\n\n| Constant | Hex |\n|---|---|\n| `color.red` | `#FF0000` |\n| `color.green` | `#00FF00` |\n| `color.blue` | `#0000FF` |\n| `color.white` | `#FFFFFF` |\n| `color.black` | `#000000` |\n| `color.yellow` | `#FFFF00` |\n| `color.orange` | `#FF9800` |\n| `color.purple` | `#9C27B0` |\n| `color.aqua` | `#00BCD4` |\n| `color.gray` | `#787B86` |\n| `color.silver` | `#9E9E9E` |\n| `color.lime` | `#8BC34A` |\n| `color.maroon` | `#880E4F` |\n| `color.navy` | `#311B92` |\n| `color.olive` | `#808000` |\n| `color.teal` | `#009688` |\n| `color.fuchsia` | `#E040FB` |\n\n### Color Functions\n\n| Function | Signature | Description |\n|---|---|---|\n| `color.new` | `(baseColor, transparency) \u2192 string` | Add transparency to a color. `transparency` is 0\u2013100 (0 = opaque, 100 = invisible) |\n| `color.rgb` | `(r, g, b, transp?) \u2192 string` | Create color from RGBA components (0\u2013255 each; transp 0\u2013100) |\n| `color.from_gradient` | `(value, bottom_value, top_value, bottom_color, top_color) \u2192 string` | Interpolate between two colors based on value position in [bottom_value, top_value] |\n\n### Hex Literals\n```\nc = #2962FF // RGB\nc = #2962FF80 // RGBA (80 = hex alpha)\n```\n\n---\n\n## 4. String \u2014 `str.*` Namespace\n\n| Function | Signature | Description |\n|---|---|---|\n| `str.tostring` | `(value) \u2192 string` | Convert any value to string |\n| `str.tonumber` | `(value) \u2192 float` | Parse string to number (NaN if invalid) |\n| `str.format` | `(template, ...args) \u2192 string` | Format with `{0}`, `{1}` placeholders |\n| `str.length` | `(s) \u2192 int` | String length |\n| `str.trim` | `(s) \u2192 string` | Remove leading/trailing whitespace |\n| `str.contains` | `(s, sub) \u2192 bool` | True if `s` contains `sub` |\n| `str.substring` | `(s, start, end?) \u2192 string` | Extract substring |\n| `str.replace_all` | `(s, target, replacement) \u2192 string` | Replace all occurrences |\n| `str.upper` | `(s) \u2192 string` | Convert to uppercase |\n| `str.lower` | `(s) \u2192 string` | Convert to lowercase |\n| `str.split` | `(s, sep?) \u2192 array` | Split into array of substrings (default sep = `\",\"`) |\n| `str.startswith` | `(s, prefix) \u2192 bool` | True if `s` starts with `prefix` |\n| `str.match` | `(s, pattern) \u2192 string` | Return first regex match, or `\"\"` if none |\n\n---\n\n## 5. Array \u2014 `array.*` Namespace\n\nArrays are mutable ordered collections. Use `var` to persist across bars.\n\n```\nvar vals = array.new_float(0) // empty float array\narray.push(vals, close) // append current close\n```\n\n### Creation\n\n| Function | Signature | Description |\n|---|---|---|\n| `array.new` | `(size, init_val) \u2192 array` | Create array of given size |\n| `array.new_float` | `(size, init_val?) \u2192 array` | Create float array |\n| `array.new_int` | `(size, init_val?) \u2192 array` | Create int array |\n| `array.new_string` | `(size, init_val?) \u2192 array` | Create string array |\n| `array.new_bool` | `(size, init_val?) \u2192 array` | Create bool array |\n| `array.from` | `(v1, v2, ...) \u2192 array` | Create from literal values |\n\n### Access and Mutation\n\n| Function | Signature | Description |\n|---|---|---|\n| `array.size` | `(arr) \u2192 int` | Number of elements |\n| `array.get` | `(arr, index) \u2192 value` | Get element at index |\n| `array.set` | `(arr, index, val) \u2192 void` | Set element at index |\n| `array.push` | `(arr, val) \u2192 void` | Append element |\n| `array.pop` | `(arr) \u2192 value` | Remove and return last element |\n| `array.remove` | `(arr, index) \u2192 value` | Remove element at index |\n| `array.clear` | `(arr) \u2192 void` | Remove all elements |\n\n### Search and Transform\n\n| Function | Signature | Description |\n|---|---|---|\n| `array.includes` | `(arr, val) \u2192 bool` | True if array contains value |\n| `array.indexof` | `(arr, val) \u2192 int` | First index of value (-1 if not found) |\n| `array.slice` | `(arr, start, end) \u2192 array` | Sub-array |\n| `array.join` | `(arr, sep?) \u2192 string` | Join elements into string |\n| `array.sort` | `(arr) \u2192 void` | Sort in place (ascending) |\n| `array.reverse` | `(arr) \u2192 void` | Reverse in place |\n\n### Aggregates\n\n| Function | Signature | Description |\n|---|---|---|\n| `array.avg` | `(arr) \u2192 float` | Average of all elements |\n| `array.sum` | `(arr) \u2192 float` | Sum of all elements |\n| `array.min` | `(arr) \u2192 float` | Minimum element |\n| `array.max` | `(arr) \u2192 float` | Maximum element |\n\n---\n\n## 6. Table \u2014 `table.*` Namespace\n\nTables render a grid of text cells on the chart. Use `var` to persist.\n\n```\nvar tbl = table.new(position.top_right, 3, 3,\n bgcolor=color.black, border_color=color.gray, border_width=1)\ntable.cell(tbl, 0, 0, \"Label\", text_color=color.white, text_size=size.small)\n```\n\n| Function | Signature | Description |\n|---|---|---|\n| `table.new` | `(position, columns, rows, bgcolor?, border_color?, border_width?, frame_color?, frame_width?) \u2192 table` | Create a table |\n| `table.cell` | `(tbl, column, row, text, text_color?, bgcolor?, text_size?, text_halign?, text_valign?) \u2192 void` | Set cell content |\n| `table.clear` | `(tbl, column, row) \u2192 void` | Clear a single cell |\n| `table.delete` | `(tbl) \u2192 void` | Delete the table |\n\n**Position:** use `position.*` constants \u2014 `position.top_right`, `position.top_left`, etc.\n**Text size:** use `size.*` constants \u2014 `size.tiny`, `size.small`, `size.normal`, `size.large`, `size.huge`\n**Alignment:** `\"left\"`, `\"center\"`, `\"right\"` for `text_halign`; `\"top\"`, `\"center\"`, `\"bottom\"` for `text_valign`\n\n---\n\n## 7. Input \u2014 `input.*` Namespace\n\nAll input functions return the default value at runtime (parameters are for UI configuration).\n\n| Function | Signature | Description |\n|---|---|---|\n| `input` | `(defval, title?) \u2192 value` | Generic parameter |\n| `input.int` | `(defval, title?, minval?, maxval?, step?) \u2192 int` | Integer parameter |\n| `input.float` | `(defval, title?, minval?, maxval?, step?) \u2192 float` | Float parameter |\n| `input.bool` | `(defval, title?) \u2192 bool` | Boolean toggle |\n| `input.string` | `(defval, title?, options?) \u2192 string` | String/dropdown parameter |\n| `input.color` | `(defval, title?) \u2192 color` | Color picker (returns the default color) |\n| `input.source` | `(defval, title?) \u2192 series` | Source selector (returns the default series) |\n| `input.text_area` | `(defval, title?) \u2192 string` | Multi-line text input |\n\n**IMPORTANT:** All `input.*` variants are fully supported. NEVER downgrade `input.int/bool/float/color` to plain `input()`. Extra named args (`tooltip`, `group`, `inline`, `confirm`, `minval`, `maxval`, `step`, `options`) are silently accepted.\n\n---\n\n## 8. Symbol Info \u2014 `syminfo.*` (Read-Only)\n\n| Property | Type | Description |\n|---|---|---|\n| `syminfo.tickerid` | string | Full ticker with exchange, e.g. `\"CME:ES1!\"` |\n| `syminfo.ticker` | string | Ticker without exchange, e.g. `\"ES1!\"` |\n| `syminfo.mintick` | float | Minimum price increment |\n| `syminfo.pointvalue` | float | Dollar value per point |\n| `syminfo.currency` | string | Quote currency |\n| `syminfo.type` | string | `\"futures\"`, `\"forex\"`, `\"crypto\"`, `\"stock\"` |\n| `syminfo.session` | string | Active session, e.g. `\"0830-1515\"` |\n| `syminfo.timezone` | string | IANA timezone, e.g. `\"America/Chicago\"` |\n\n---\n\n## 9. Bar State \u2014 `barstate.*` (Read-Only)\n\n| Property | Type | Description |\n|---|---|---|\n| `barstate.islast` | bool | True on the most recent bar |\n| `barstate.isfirst` | bool | True on bar 0 |\n| `barstate.isconfirmed` | bool | True \u2014 all historical bars are confirmed |\n| `barstate.isnew` | bool | True \u2014 each bar is new in per-bar execution |\n| `barstate.isrealtime` | bool | False \u2014 ForgeScript runs on historical data |\n| `barstate.ishistory` | bool | True |\n\n---\n\n## 10. Timeframe \u2014 `timeframe.*` (Read-Only)\n\n| Property | Type | Description |\n|---|---|---|\n| `timeframe.period` | string | Current timeframe period string, e.g. `\"1\"`, `\"D\"` |\n| `timeframe.multiplier` | int | Numeric multiplier, e.g. `1`, `60` |\n| `timeframe.isintraday` | bool | True |\n| `timeframe.isdaily` | bool | False |\n| `timeframe.isweekly` | bool | False |\n| `timeframe.ismonthly` | bool | False |\n\n---\n\n## 11. Time Functions (flat calls)\n\nExtract date/time components from a Unix millisecond timestamp.\nAll functions accept an optional `time` argument (defaults to current bar's `time`).\n\n| Function | Signature | Description |\n|---|---|---|\n| `year` | `(time?) \u2192 int` | 4-digit year, e.g. 2024 |\n| `month` | `(time?) \u2192 int` | Month 1\u201312 |\n| `dayofmonth` | `(time?) \u2192 int` | Day of month 1\u201331 |\n| `dayofweek` | `(time?) \u2192 int` | Day of week: 1=Sunday \u2026 7=Saturday |\n| `hour` | `(time?) \u2192 int` | Hour 0\u201323 (UTC) |\n| `minute` | `(time?) \u2192 int` | Minute 0\u201359 |\n| `second` | `(time?) \u2192 int` | Second 0\u201359 |\n| `timestamp` | `(year, month, day, hour?, minute?, second?) \u2192 int` | Construct Unix ms timestamp |\n\n```\nif hour(time) == 9 and minute(time) == 30\n plotshape(true, style=\"circle\", location=\"abovebar\", color=color.yellow, text=\"Open\")\n\nsessionStart = timestamp(year(time), month(time), dayofmonth(time), 9, 30, 0)\n```\n\n---\n\n## 12. Enum-Like Namespaces\n\nThese namespaces return their property name as a string constant.\n\n| Namespace | Example Values |\n|---|---|\n| `position.*` | `top_right`, `top_left`, `top_center`, `middle_left`, `middle_center`, `middle_right`, `bottom_left`, `bottom_center`, `bottom_right` |\n| `size.*` | `tiny`, `small`, `normal`, `large`, `huge`, `auto` |\n| `shape.*` | `circle`, `square`, `diamond`, `triangleup`, `triangledown`, `flag`, `labelup`, `labeldown`, `xcross`, `cross`, `arrowup`, `arrowdown` |\n| `location.*` | `abovebar`, `belowbar`, `top`, `bottom`, `absolute` |\n| `text.*` | `align_left` \u2192 `\"left\"`, `align_center` \u2192 `\"center\"`, `align_right` \u2192 `\"right\"`, `align_top` \u2192 `\"top\"`, `align_bottom` \u2192 `\"bottom\"` |\n| `plot.*` | `style_line` \u2192 `\"line\"`, `style_histogram` \u2192 `\"histogram\"`, `style_circles` \u2192 `\"circles\"`, `style_area` \u2192 `\"area\"`, `style_columns` \u2192 `\"columns\"`, `style_stepline` \u2192 `\"stepline\"` |\n\n---\n\n## 13. Built-in Data Series\n\nAlways available without declaration:\n\n| Name | Type | Description |\n|---|---|---|\n| `open` | series float | Bar open price |\n| `high` | series float | Bar high price |\n| `low` | series float | Bar low price |\n| `close` | series float | Bar close price |\n| `volume` | series float | Bar volume |\n| `time` | series int | Bar open time (Unix milliseconds) |\n| `hl2` | series float | `(high + low) / 2` |\n| `hlc3` | series float | `(high + low + close) / 3` |\n| `ohlc4` | series float | `(open + high + low + close) / 4` |\n| `bar_index` | int | Zero-based bar count |\n\n---\n\n## 14. Utility Functions\n\n| Function | Signature | Description |\n|---|---|---|\n| `indicator` | `(title, overlay?, precision?) \u2192 void` | Declare indicator name and settings |\n| `na` | `(value?) \u2192 bool|float` | Test if value is na, or the na constant itself |\n| `nz` | `(value, replacement?) \u2192 float` | Replace na with 0 or custom replacement |\n\n\n## 9. Data Requests (`request.*`)\n\nFunctions for accessing external data and multi-timeframe (MTF) series.\n\n| Function | Description |\n|----------|-------------|\n| `request.security(symbol, timeframe, expression)` | Evaluates `expression` on the specified `symbol` and `timeframe` (e.g., `\"AAPL\"`, `\"D\"`, `close`). Returns `NaN` if the host has not loaded the requested MTF data. |\n| `request.data(datasetName, column)` | Looks up the value of `column` in a user-imported dataset named `datasetName` at the current bar's time. If `column` is omitted, defaults to `\"value\"`. Returns `NaN` if the dataset or column does not exist. |\n\n## EXAMPLES \u2014 BASIC\n\n# ForgeScript Examples \u2014 Basic Indicators\n\nThese examples demonstrate correct ForgeScript syntax for common indicators.\nAll examples are valid, tested ForgeScript code.\n\n---\n\n## 1. Simple Moving Average (SMA)\n\n```forgescript\nindicator(\"SMA Indicator\", overlay=true)\nlength = input(14, title=\"Length\")\nsrc = close\nsmaVal = sma(src, length)\nplot(smaVal, title=\"SMA\", color=#2196F3, linewidth=2)\n```\n\n**Key points:**\n- `input()` lets users configure parameters\n- `sma()` computes a rolling simple moving average\n- `plot()` draws the result on the chart\n- `overlay=true` renders on the price pane\n\n---\n\n## 2. Exponential Moving Average (EMA)\n\n```forgescript\nindicator(\"EMA Crossover\", overlay=true)\nfastLen = input(9, title=\"Fast EMA\")\nslowLen = input(21, title=\"Slow EMA\")\nfastEma = ema(close, fastLen)\nslowEma = ema(close, slowLen)\nplot(fastEma, title=\"Fast EMA\", color=#2196F3, linewidth=2)\nplot(slowEma, title=\"Slow EMA\", color=#FF6D00, linewidth=2)\n```\n\n---\n\n## 3. Relative Strength Index (RSI)\n\n```forgescript\nindicator(\"RSI\", overlay=false)\nlength = input(14, title=\"RSI Period\")\nsrc = close\nrsiVal = rsi(src, length)\nplot(rsiVal, title=\"RSI\", color=#2196F3, linewidth=2)\nhline(70, title=\"Overbought\", color=#FF0000, linestyle=\"dashed\")\nhline(30, title=\"Oversold\", color=#00FF00, linestyle=\"dashed\")\nhline(50, title=\"Midline\", color=#787B86, linestyle=\"dotted\")\n```\n\n**Key points:**\n- `overlay=false` renders in a separate sub-pane\n- `hline()` draws horizontal reference lines\n- RSI ranges from 0 to 100\n\n---\n\n## 4. MACD (Moving Average Convergence Divergence)\n\n```forgescript\nindicator(\"MACD\", overlay=false)\nfastLen = input(12, title=\"Fast Length\")\nslowLen = input(26, title=\"Slow Length\")\nsignalLen = input(9, title=\"Signal Length\")\nmacdVal = macd(close, fastLen, slowLen, signalLen)\nplot(macdVal, title=\"MACD\", color=#2196F3, linewidth=2)\nplot(__macd_signal, title=\"Signal\", color=#FF6D00, linewidth=1)\nplot(__macd_hist, title=\"Histogram\", color=#26a69a, style=\"histogram\")\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\n```\n\n**Key points:**\n- `macd()` returns the MACD line value\n- `__macd_signal` and `__macd_hist` are automatically populated after `macd()` is called\n- Use `style=\"histogram\"` for the histogram bars\n\n---\n\n## 5. Bollinger Bands\n\n```forgescript\nindicator(\"Bollinger Bands\", overlay=true)\nlength = input(20, title=\"Length\")\nmult = input(2, title=\"Multiplier\")\nbasis = sma(close, length)\ndevVal = mult * stdev(close, length)\nupper = basis + devVal\nlower = basis - devVal\np1 = plot(upper, title=\"Upper\", color=#FF000080)\np2 = plot(lower, title=\"Lower\", color=#00FF0080)\nfill(p1, p2, color=#2196F320, title=\"BB Zone\")\nplot(basis, title=\"Basis\", color=#FF6D00, linewidth=2)\n```\n\n**Key points:**\n- `stdev()` computes rolling standard deviation\n- `fill()` shades the area between two plots\n- Color alpha suffix (`80`, `20`) controls transparency\n\n---\n\n## 6. Simple Crossover Signal\n\n```forgescript\nindicator(\"Golden/Death Cross\", overlay=true)\nfast = sma(close, 50)\nslow = sma(close, 200)\nplot(fast, title=\"SMA 50\", color=#2196F3, linewidth=2)\nplot(slow, title=\"SMA 200\", color=#FF6D00, linewidth=2)\nplotshape(crossover(fast, slow), style=\"triangleup\", location=\"belowbar\", color=#00FF00, text=\"Golden\")\nplotshape(crossunder(fast, slow), style=\"triangledown\", location=\"abovebar\", color=#FF0000, text=\"Death\")\n```\n\n**Key points:**\n- `crossover(a, b)` is true when `a` crosses above `b`\n- `crossunder(a, b)` is true when `a` crosses below `b`\n- `plotshape()` only emits a marker when the condition is true\n\n---\n\n## 7. Average True Range (ATR)\n\n```forgescript\nindicator(\"ATR\", overlay=false)\nlength = input(14, title=\"ATR Period\")\natrVal = atr(length)\nplot(atrVal, title=\"ATR\", color=#FF6D00, linewidth=2)\n```\n\n---\n\n## 8. Stochastic Oscillator\n\n```forgescript\nindicator(\"Stochastic\", overlay=false)\nkLen = input(14, title=\"%K Length\")\nkVal = stoch(close, high, low, kLen)\ndVal = sma(kVal, 3)\nplot(kVal, title=\"%K\", color=#2196F3, linewidth=2)\nplot(dVal, title=\"%D\", color=#FF6D00, linewidth=1)\nhline(80, title=\"Overbought\", color=#FF0000, linestyle=\"dashed\")\nhline(20, title=\"Oversold\", color=#00FF00, linestyle=\"dashed\")\n```\n\n---\n\n## 9. On-Balance Volume (OBV)\n\n```forgescript\nindicator(\"OBV\", overlay=false)\nobvVal = obv()\nobvSma = sma(obvVal, 20)\nplot(obvVal, title=\"OBV\", color=#2196F3, linewidth=2)\nplot(obvSma, title=\"OBV SMA\", color=#FF6D00, linewidth=1)\n```\n\n---\n\n## 10. Stateful Accumulator with var\n\n```forgescript\nindicator(\"Cumulative Delta\", overlay=false)\nvar cumDelta = 0\ndelta = close - open\ncumDelta := cumDelta + delta\nplot(cumDelta, title=\"Cum Delta\", color=#2196F3, linewidth=2)\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\n```\n\n**Key points:**\n- `var cumDelta = 0` initializes once (persists across bars)\n- `cumDelta := cumDelta + delta` reassigns on each bar\n- The `=` is for first declaration, `:=` is for reassignment\n\n---\n\n## 11. Momentum\n\n```forgescript\nindicator(\"Momentum\", overlay=false)\nlength = input(10, title=\"Length\")\nmomVal = mom(close, length)\nplot(momVal, title=\"Momentum\", color=#2196F3, linewidth=2)\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\nbgcolor(momVal > 0 ? #00FF0010 : #FF000010)\n```\n\n---\n\n## 12. Price Change\n\n```forgescript\nindicator(\"Daily Change\", overlay=false)\nchg = change(close)\nplot(chg, title=\"Change\", color=#2196F3, style=\"histogram\")\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\nbarcolor(chg > 0 ? #26a69a : #ef5350)\n```\n\n## EXAMPLES \u2014 ADVANCED\n\n# ForgeScript Examples \u2014 Advanced Indicators\n\nThese examples demonstrate more complex ForgeScript patterns.\nAll examples are valid, tested ForgeScript code.\n\n---\n\n## 1. Multi-Indicator Dashboard\n\n```forgescript\nindicator(\"Trend Dashboard\", overlay=false)\n\n// Moving averages for trend\nfast = ema(close, 9)\nslow = ema(close, 21)\n\n// Momentum\nrsiVal = rsi(close, 14)\nmomVal = mom(close, 10)\n\n// Trend score: +1 per bullish signal\nscore = 0\nif fast > slow\n score := score + 1\nif rsiVal > 50\n score := score + 1\nif momVal > 0\n score := score + 1\n\nplot(score, title=\"Trend Score\", color=#2196F3, style=\"histogram\")\nhline(0, title=\"Neutral\", color=#787B86, linestyle=\"dotted\")\nhline(3, title=\"Full Bull\", color=#00FF00, linestyle=\"dashed\")\nbgcolor(score == 3 ? #00FF0015 : score == 0 ? #FF000015 : na)\n```\n\n**Key points:**\n- Combine multiple indicators into a single score\n- Use `if` blocks to conditionally update `score` with `:=`\n- Initial `score = 0` uses `=`, subsequent updates use `:=`\n\n---\n\n## 2. Volatility-Adjusted Bands\n\n```forgescript\nindicator(\"Keltner Channels\", overlay=true)\nlength = input(20, title=\"Length\")\nmult = input(1.5, title=\"ATR Multiplier\")\n\nbasis = ema(close, length)\natrVal = atr(length)\nupper = basis + mult * atrVal\nlower = basis - mult * atrVal\n\np1 = plot(upper, title=\"Upper\", color=#FF000060)\np2 = plot(lower, title=\"Lower\", color=#00FF0060)\nfill(p1, p2, color=#2196F315, title=\"Channel\")\nplot(basis, title=\"Basis\", color=#FF6D00, linewidth=2)\n\n// Breakout detection\nplotshape(close > upper, style=\"triangleup\", location=\"belowbar\", color=#00FF00, text=\"Break\")\nplotshape(close < lower, style=\"triangledown\", location=\"abovebar\", color=#FF0000, text=\"Break\")\n```\n\n---\n\n## 3. RSI Divergence Detector\n\n```forgescript\nindicator(\"RSI with Divergence\", overlay=false)\nlength = input(14, title=\"RSI Length\")\nlookback = input(5, title=\"Lookback\")\n\nrsiVal = rsi(close, length)\n\n// Detect potential bullish divergence:\n// Price making lower lows while RSI making higher lows\npriceLow = lowest(close, lookback)\nrsiLow = lowest(rsiVal, lookback)\nprevPriceLow = lowest(close[lookback], lookback)\nprevRsiLow = lowest(rsiVal[lookback], lookback)\n\nbullDiv = priceLow < prevPriceLow and rsiLow > prevRsiLow\n\nplot(rsiVal, title=\"RSI\", color=#2196F3, linewidth=2)\nhline(70, title=\"Overbought\", color=#FF0000, linestyle=\"dashed\")\nhline(30, title=\"Oversold\", color=#00FF00, linestyle=\"dashed\")\nplotshape(bullDiv, style=\"diamond\", location=\"bottom\", color=#00FF00, text=\"Div\")\nbgcolor(bullDiv ? #00FF0020 : na)\n```\n\n---\n\n## 4. Custom Signal with Multiple Confirmations\n\n```forgescript\nindicator(\"Triple Confirmation\", overlay=true)\n\n// Signal 1: EMA crossover\nfast = ema(close, 9)\nslow = ema(close, 21)\nemaCross = crossover(fast, slow)\n\n// Signal 2: RSI confirmation\nrsiVal = rsi(close, 14)\nrsiBull = rsiVal > 50\n\n// Signal 3: Volume confirmation\nvolSma = sma(volume, 20)\nvolSpike = volume > 1.5 * volSma\n\n// Combined signal\nbuySignal = emaCross and rsiBull and volSpike\n\nplot(fast, title=\"Fast EMA\", color=#2196F3, linewidth=1)\nplot(slow, title=\"Slow EMA\", color=#FF6D00, linewidth=1)\nplotshape(buySignal, style=\"label_up\", location=\"belowbar\", color=#00FF00, text=\"BUY\")\nbgcolor(buySignal ? #00FF0020 : na)\n```\n\n---\n\n## 5. Layered Plots with Fills\n\n```forgescript\nindicator(\"Triple EMA Ribbon\", overlay=true)\nema8 = ema(close, 8)\nema13 = ema(close, 13)\nema21 = ema(close, 21)\nema55 = ema(close, 55)\n\np1 = plot(ema8, title=\"EMA 8\", color=#4CAF50)\np2 = plot(ema13, title=\"EMA 13\", color=#8BC34A)\np3 = plot(ema21, title=\"EMA 21\", color=#FF9800)\np4 = plot(ema55, title=\"EMA 55\", color=#F44336)\n\nfill(p1, p2, color=#4CAF5020)\nfill(p2, p3, color=#8BC34A20)\nfill(p3, p4, color=#FF980020)\n```\n\n---\n\n## 6. Dynamic Support/Resistance\n\n```forgescript\nindicator(\"Pivot Points\", overlay=true)\nleftBars = input(5, title=\"Left Bars\")\nrightBars = input(5, title=\"Right Bars\")\n\npvtHigh = pivothigh(high, leftBars, rightBars)\npvtLow = pivotlow(low, leftBars, rightBars)\n\nplot(pvtHigh, title=\"Pivot High\", color=#FF0000, style=\"circles\", linewidth=3)\nplot(pvtLow, title=\"Pivot Low\", color=#00FF00, style=\"circles\", linewidth=3)\n```\n\n**Key points:**\n- `pivothigh()` and `pivotlow()` return `NaN` when no pivot is detected\n- `NaN` values are automatically filtered from plot output\n- `style=\"circles\"` renders only at pivot points\n\n---\n\n## 7. Volume Profile Indicator\n\n```forgescript\nindicator(\"Volume Analysis\", overlay=false)\nvolSma = sma(volume, 20)\nvolRatio = volume / volSma\n\nplot(volRatio, title=\"Vol Ratio\", color=#2196F3, style=\"histogram\")\nhline(1.0, title=\"Average\", color=#787B86, linestyle=\"dashed\")\nhline(2.0, title=\"High Volume\", color=#FF0000, linestyle=\"dashed\")\n\nbarcolor(volRatio > 2.0 ? #FF0000 : volRatio > 1.5 ? #FF6D00 : na)\nbgcolor(volRatio > 2.0 ? #FF000015 : na)\n```\n\n---\n\n## 8. Rolling High/Low Channel\n\n```forgescript\nindicator(\"Donchian Channel\", overlay=true)\nlength = input(20, title=\"Channel Length\")\n\nupperCh = highest(high, length)\nlowerCh = lowest(low, length)\nmidCh = (upperCh + lowerCh) / 2\n\np1 = plot(upperCh, title=\"Upper\", color=#FF0000)\np2 = plot(lowerCh, title=\"Lower\", color=#00FF00)\nfill(p1, p2, color=#2196F310)\nplot(midCh, title=\"Mid\", color=#FF6D00, linewidth=2, style=\"stepline\")\n```\n\n---\n\n## 9. Correlation Indicator\n\n```forgescript\nindicator(\"Price-Volume Correlation\", overlay=false)\nlength = input(20, title=\"Length\")\ncorrVal = correlation(close, volume, length)\n\nplot(corrVal, title=\"Correlation\", color=#2196F3, linewidth=2)\nhline(0.5, title=\"Strong Positive\", color=#00FF00, linestyle=\"dashed\")\nhline(-0.5, title=\"Strong Negative\", color=#FF0000, linestyle=\"dashed\")\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\nbgcolor(corrVal > 0.5 ? #00FF0015 : corrVal < -0.5 ? #FF000015 : na)\n```\n\n---\n\n## 10. Momentum with Lookback Comparison\n\n```forgescript\nindicator(\"Rate of Change\", overlay=false)\nlength = input(12, title=\"ROC Length\")\nroc = (close - close[length]) / close[length] * 100\n\nplot(roc, title=\"ROC %\", color=#2196F3, linewidth=2)\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\n\n// Color bars based on momentum direction\nbarcolor(roc > 0 and roc > roc[1] ? #00FF00 : roc < 0 and roc < roc[1] ? #FF0000 : na)\n\n// Mark extreme moves\nplotshape(roc > 10, style=\"flag\", location=\"top\", color=#00FF00, text=\"Strong\")\nplotshape(roc < -10, style=\"flag\", location=\"bottom\", color=#FF0000, text=\"Weak\")\n```\n\n## PLOTTING\n\n# ForgeScript Plotting & Output Functions\n\nForgeScript output functions emit visual data from each bar execution.\nEvery output function is called once per bar during the bar-by-bar execution loop.\n\n---\n\n## 1. plot()\n\nDraw a continuous series line on the chart.\n\n```\nplot(value, title=, color=, linewidth=, style=)\n```\n\n| Parameter | Type | Default | Description |\n|-------------|--------|-------------|-------------|\n| value | number | required | Series value to plot |\n| title | string | \"Plot N\" | Legend label |\n| color | string | \u2014 | Hex color `#RRGGBB` or `#RRGGBBAA` |\n| linewidth | number | 1 | Line thickness in pixels |\n| style | string | \"line\" | Drawing style (see below) |\n\n**Supported styles:**\n`\"line\"`, `\"histogram\"`, `\"circles\"`, `\"cross\"`, `\"area\"`, `\"columns\"`, `\"stepline\"`, `\"stepline_diamond\"`\n\n**Returns:** the `value` parameter (number).\n\n**Example:**\n```forgescript\nindicator(\"SMA Plot\", overlay=true)\nsmaVal = sma(close, 20)\nplot(smaVal, title=\"SMA 20\", color=#2196F3, linewidth=2, style=\"line\")\n```\n\n---\n\n## 2. plotshape()\n\nDraw a shape marker when a boolean condition is true.\n\n```\nplotshape(condition, style=, location=, color=, text=, title=)\n```\n\n| Parameter | Type | Default | Description |\n|-------------|---------|--------------|-------------|\n| condition | boolean | required | Emit shape when true |\n| style | string | \"xcross\" | Shape type (see below) |\n| location | string | \"abovebar\" | Placement on chart |\n| color | string | \u2014 | Hex color |\n| text | string | \u2014 | Label text on the shape |\n| title | string | \u2014 | Legend label |\n\n**Supported styles:**\n`\"xcross\"`, `\"cross\"`, `\"circle\"`, `\"triangleup\"`, `\"triangledown\"`, `\"flag\"`, `\"diamond\"`, `\"arrowup\"`, `\"arrowdown\"`, `\"square\"`, `\"label_up\"`, `\"label_down\"`\n\n**Supported locations:**\n`\"abovebar\"`, `\"belowbar\"`, `\"top\"`, `\"bottom\"`, `\"absolute\"`\n\n**Returns:** `NaN`\n\n**Example:**\n```forgescript\nindicator(\"Crossover Shapes\")\nfast = sma(close, 5)\nslow = sma(close, 20)\nplotshape(crossover(fast, slow), style=\"triangleup\", location=\"belowbar\", color=#00FF00, text=\"BUY\")\nplotshape(crossunder(fast, slow), style=\"triangledown\", location=\"abovebar\", color=#FF0000, text=\"SELL\")\n```\n\n---\n\n## 3. plotchar()\n\nAlias for `plotshape()` \u2014 renders character/marker shapes with identical parameters.\n\n```\nplotchar(condition, style=, location=, color=, text=, title=)\n```\n\nInternally calls the same handler as `plotshape()`.\n\n---\n\n## 4. plotarrow()\n\nDraw directional arrows based on the sign of a value.\n\n```\nplotarrow(value, colorup=, colordown=)\n```\n\n| Parameter | Type | Default | Description |\n|------------|--------|-------------|-------------|\n| value | number | required | Positive = up arrow, negative = down arrow |\n| colorup | string | \"#00FF00\" | Color for upward arrows |\n| colordown | string | \"#FF0000\" | Color for downward arrows |\n\n**Returns:** `value` (number)\n\n**Example:**\n```forgescript\nindicator(\"Momentum Arrows\")\ndelta = change(close)\nplotarrow(delta, colorup=#26a69a, colordown=#ef5350)\n```\n\n---\n\n## 5. hline()\n\nDraw a horizontal reference line at a fixed price level.\n\n```\nhline(price, title=, color=, linestyle=, linewidth=)\n```\n\n| Parameter | Type | Default | Description |\n|------------|--------|-------------|-------------|\n| price | number | required | Y-axis price level |\n| title | string | \u2014 | Line label |\n| color | string | \"#787B86\" | Hex color |\n| linestyle | string | \"dashed\" | `\"dashed\"`, `\"solid\"`, `\"dotted\"` |\n| linewidth | number | 1 | Line thickness |\n\n**Returns:** `price` (number)\n\n**Deduplication:** Only one hline per price value is stored. Duplicate prices are ignored.\n\n**Example:**\n```forgescript\nindicator(\"RSI Levels\", overlay=false)\nrsiVal = rsi(close, 14)\nhline(70, title=\"Overbought\", color=#FF0000, linestyle=\"dashed\")\nhline(30, title=\"Oversold\", color=#00FF00, linestyle=\"dashed\")\nhline(50, title=\"Midline\", color=#787B86, linestyle=\"dotted\")\nplot(rsiVal, title=\"RSI\", color=#2196F3)\n```\n\n---\n\n## 6. fill()\n\nFill the region between two plot or hline outputs.\n\n```\nfill(id1, id2, color=, title=)\n```\n\n| Parameter | Type | Default | Description |\n|-----------|--------|---------------|-------------|\n| id1 | ref | required | First plot or hline reference |\n| id2 | ref | required | Second plot or hline reference |\n| color | string | \"#00000020\" | Fill color (use alpha for transparency) |\n| title | string | \u2014 | Fill label |\n\n**Returns:** `NaN`\n\n**Example:**\n```forgescript\nindicator(\"Bollinger Band Fill\", overlay=true)\nbasis = sma(close, 20)\ndev = 2 * stdev(close, 20)\nupper = basis + dev\nlower = basis - dev\np1 = plot(upper, title=\"Upper\", color=#FF000080)\np2 = plot(lower, title=\"Lower\", color=#00FF0080)\nfill(p1, p2, color=#2196F320, title=\"BB Zone\")\nplot(basis, title=\"Basis\", color=#FF6D00)\n```\n\n---\n\n## 7. bgcolor()\n\nSet the background color of the chart for the current bar.\n\n```\nbgcolor(color)\n```\n\n| Parameter | Type | Description |\n|-----------|--------|-------------|\n| color | string | Hex color (use alpha for semi-transparency, e.g. `#FF000030`) |\n\n**Returns:** `NaN`\n\nUse `na` to skip coloring a bar:\n```forgescript\nbgcolor(close > open ? #00FF0020 : na)\n```\n\n---\n\n## 8. barcolor()\n\nOverride the OHLC candlestick color for the current bar.\n\n```\nbarcolor(color)\n```\n\n| Parameter | Type | Description |\n|-----------|--------|-------------|\n| color | string | Hex color |\n\n**Returns:** `NaN`\n\nUse `na` to keep default color:\n```forgescript\nrsiVal = rsi(close, 14)\nbarcolor(rsiVal > 70 ? #FF0000 : rsiVal < 30 ? #00FF00 : na)\n```\n\n---\n\n## 9. Output Metadata Structure\n\nWhen a ForgeScript indicator runs via `runFull()`, the result contains:\n\n| Field | Type | Description |\n|-------------|-------------------|-------------|\n| plots | IndicatorPoint[][] | One array per `plot()` call, ordered by declaration |\n| plotMetas | PlotMeta[] | Title, color, linewidth, style per plot |\n| hlines | HLineMeta[] | Horizontal line definitions |\n| fills | FillMeta[] | Fill region definitions |\n| bgcolors | BgColorEntry[] | Per-bar background colors |\n| barcolors | BarColorEntry[] | Per-bar candlestick colors |\n| shapes | ShapeEntry[] | Plotshape/plotchar/plotarrow markers |\n| overlay | boolean | From indicator() declaration |\n| title | string | From indicator() declaration |\n\nEach `IndicatorPoint` is `{ time: number, value: number }`. `NaN` values are filtered out.\n\n---\n\n## 10. Common Patterns\n\n### Multi-plot indicator\n```forgescript\nindicator(\"MACD\", overlay=false)\nmacdVal = macd(close, 12, 26, 9)\nplot(macdVal, title=\"MACD\", color=#2196F3)\nplot(__macd_signal, title=\"Signal\", color=#FF6D00)\nplot(__macd_hist, title=\"Histogram\", color=#26a69a, style=\"histogram\")\nhline(0, title=\"Zero\", color=#787B86, linestyle=\"dotted\")\n```\n\n### Conditional shapes with plot\n```forgescript\nindicator(\"Overbought/Oversold\", overlay=false)\nval = rsi(close, 14)\nplot(val, title=\"RSI\", color=#2196F3)\nplotshape(val > 70, style=\"triangledown\", location=\"top\", color=#FF0000)\nplotshape(val < 30, style=\"triangleup\", location=\"bottom\", color=#00FF00)\n```\n\n### Background shading\n```forgescript\nindicator(\"Session Highlight\", overlay=true)\nisUp = close > open\nbgcolor(isUp ? #00FF0010 : #FF000010)\nplot(close, title=\"Close\")\n```\n\n## RUNTIME RULES\n\n# ForgeScript Runtime Rules & Constraints\n\nAll ForgeScript code runs inside a sandboxed tree-walking interpreter.\nThese rules define execution limits, permissions, and safety boundaries.\n\n---\n\n## 1. Execution Model\n\nForgeScript uses a **bar-by-bar execution model**:\n\n1. The entire program runs once per OHLCV bar, from top to bottom\n2. Built-in data series (`open`, `high`, `low`, `close`, `volume`, `time`) are updated before each bar\n3. Derived series (`hl2`, `hlc3`, `ohlc4`, `bar_index`) are computed automatically\n4. All statements execute sequentially \u2014 no parallelism, no async\n5. After each bar, plot values are accumulated into output arrays\n\nThere is no event loop, no callbacks, no deferred execution.\n\n---\n\n## 2. Series Ring Buffers\n\nEvery series (built-in or user-created) is backed by a **ring buffer**:\n\n- Default capacity: **1000 bars** of history\n- `series[n]` accesses n bars ago (0 = current bar)\n- Accessing beyond buffer capacity returns `NaN`\n- New values overwrite the oldest when the buffer is full\n\n---\n\n## 3. Loop Iteration Limits\n\n| Loop Type | Maximum Iterations | Error on Exceed |\n|-----------|-------------------|-----------------|\n| `while` | 10,000 | RangeError |\n| `for` | 100,000 | RangeError |\n| `for..in` | No explicit limit (bounded by array size) | \u2014 |\n\n---\n\n## 4. Sandbox Execution (Conversion Pipeline)\n\nWhen ForgeScript is generated by the AI conversion system, it runs through a sandbox:\n\n- **Test data:** 200 synthetic OHLCV bars\n- **Timeout:** 5,000ms wall-clock limit\n- **Isolation:** Fresh `ForgeScriptIndicator` instance, no shared state\n\n### Sandbox result:\n- `ok: true` \u2014 compiled and executed without errors\n- `ok: false` \u2014 compile error, runtime error, or timeout\n\n---\n\n## 5. Variable Scoping\n\n- `x = expr` \u2014 new variable, re-evaluated every bar\n- `var x = expr` \u2014 initialized once on bar 0, persists across bars\n- `varip x = expr` \u2014 initialized once, updates intra-bar on real-time ticks\n- `x := expr` \u2014 reassigns an existing variable (must be previously declared)\n- All variables are **script-scoped** \u2014 no block scoping\n- Variables declared inside `if`/`for`/`while` are visible everywhere in the script\n\n---\n\n## 6. User-Defined Functions\n\nForgeScript supports user-defined functions with Pine `=>` syntax.\n\n```forgescript\nf_zscore(src, length) =>\n m = sma(src, length)\n s = stdev(src, length)\n s != 0 ? (src - m) / s : 0.0\n```\n\n- Parameters are passed by value\n- No recursion\n- Functions are hoisted \u2014 can be called before they are defined in the source\n- All function names are script-scoped (no namespacing of user functions)\n\n---\n\n## 7. Permission Gating\n\n### request.security() & request.data()\n- `request.security(symbol, timeframe, expression)` evaluates the expression on the specified symbol and timeframe.\n- `request.data(datasetName, column)` fetches values from user-imported external datasets (CSV/JSON).\n- Both functions return `NaN` if the data is not available.\n\n---\n\n## 8. What ForgeScript Cannot Do\n\n| Category | Unavailable |\n|----------|-------------|\n| **Trading** | `strategy.*`, order placement, position management |\n| **Alerts** | `alertcondition`, `alert` |\n| **Advanced collections** | `matrix.*`, `map.*` |\n| **Modules** | `import`, `export`, `library` |\n| **OOP** | Classes, interfaces, inheritance, `type` (UDT) |\n| **Async** | Promises, callbacks, event listeners |\n| **I/O** | File read/write, network requests, database access |\n| **Logging** | `log.*`, `print`, `console.*` |\n| **Error handling** | `try`/`catch`/`finally` |\n| **MTF data** | `request.security()` (fully supported) |\n\n---\n\n## 9. What ForgeScript CAN Do (common misconceptions)\n\nThese features **are fully supported** \u2014 do not warn about them:\n\n| Feature | Notes |\n|---------|-------|\n| `array.*` (all 22+ methods) | Full array support with `var` persistence |\n| `table.new()` / `table.cell()` | Renders on-chart text panels |\n| `label.new()`, `line.new()`, `box.new()` | **Not yet implemented** \u2014 remove from converted scripts |\n| `str.*` (all 13 functions) | Including `startswith`, `match`, `split` |\n| `input.int/float/bool/string/source/text_area` | All typed input variants work |\n| `barstate.*` | `islast`, `isfirst`, `isconfirmed`, etc. |\n| `timeframe.*` | `period`, `multiplier`, `isintraday`, etc. |\n| User-defined functions (`f(x) => ...`) | Single-expression and multi-line block forms |\n| `for x in array` | Array iteration loop |\n| `break` / `continue` | Loop control statements |\n| `year()`, `month()`, `hour()`, etc. | Time extraction from Unix ms timestamps |\n| `color.from_gradient()` | Gradient color interpolation |\n| `plotshape()`, `plotchar()`, `plotarrow()` | Shape markers rendered on chart |\n| `hline()` | Horizontal reference lines rendered on chart |\n| `fill()` | Fill between hlines |\n| `bgcolor()` | Per-bar background color |\n| `barcolor()` | Per-bar candle color strip |\n\n---\n\n## 10. Indicator Declaration\n\n```forgescript\nindicator(\"Title\", overlay=false)\n```\n\n| Parameter | Type | Default | Description |\n|---------------|---------|---------|-------------|\n| title | string | required | Display name |\n| overlay | boolean | false | true = render on price pane |\n| max_bars_back | number | \u2014 | Parsed but not enforced |\n\n---\n\n## 11. Error Handling\n\nForgeScript has no try/catch. Errors propagate immediately:\n\n| Error Type | Cause | Effect |\n|------------|-------|--------|\n| Compile error | Invalid syntax | Script does not run at all |\n| ReferenceError | Undefined variable, unknown function | Bar execution halts |\n| RangeError | Loop iteration limit exceeded | Bar execution halts |\n| Timeout | Execution exceeds 5s in sandbox | Sandbox returns failure |\n\n---\n\n## 12. Determinism\n\nForgeScript execution is **deterministic**:\n- Same source + same bars = same output, always\n- `math.random()` is the only non-deterministic function\n- Plot output order matches declaration order in the source\n\n## UNSUPPORTED \u2014 DO NOT USE\n\n# ForgeScript Unsupported Features\n\nThis document catalogs every feature that ForgeScript does NOT support.\nWhen the AI encounters any of these in source code, it MUST:\n1. Report the feature in the `unsupportedFeatures` array\n2. Add a warning explaining why it cannot be converted\n3. Provide the closest approximation where possible, or omit the code\n\n---\n\n## 1. Trading & Strategy\n\nForgeScript is for **indicators only** \u2014 no trading execution.\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| `strategy()` declaration | Not supported | Use `indicator()` instead \u2014 cannot convert strategies |\n| `strategy.entry()` | Not supported | Use `plotshape()` to mark entry signals |\n| `strategy.exit()` | Not supported | Use `plotshape()` to mark exit signals |\n| `strategy.close()` | Not supported | None |\n| `strategy.order()` | Not supported | None |\n| `strategy.position_size` | Not supported | None |\n| `strategy.equity` | Not supported | None |\n| `strategy.profit` | Not supported | None |\n| Any other `strategy.*` member | Not supported | Report as unsupported |\n\n---\n\n\n\n## 3. Multi-Timeframe & External Data\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| `request.financial()` | Not supported | None |\n| `request.quandl()` | Not supported | None |\n| `request.dividends()` | Not supported | None |\n| `request.earnings()` | Not supported | None |\n| `request.splits()` | Not supported | None |\n\n---\n\n\n\n## 5. User-Defined Types (UDT)\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| Python: `class MyClass` | Not supported | Use separate variables |\n| JavaScript: `class MyClass` | Not supported | Use separate variables |\n| Enums | Not supported | Use numeric constants |\n\n## 6. Modules & Imports\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| `export` | Not supported | Not applicable |\n| `require()` | Not supported | Inline the logic |\n\n## 7. Color Extraction\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| `color.r(c)` / `color.g(c)` / `color.b(c)` | Not supported | None |\n\n---\n\n## 8. Error Handling\n\n| Feature | Status | Approximation |\n|---------|--------|---------------|\n| `finally` | Not supported | None |\n| `runtime.error()` | Not supported | None |\n\n## 9. I/O & External Resources\n\nEverything in this category is strictly prohibited.\n\n| Feature | Status |\n|---------|--------|\n| File reading/writing | Not supported |\n| HTTP requests | Not supported |\n| Database queries | Not supported |\n| WebSocket connections | Not supported |\n| Console output / logging | Not supported |\n| Environment variables | Not supported |\n| Process execution | Not supported |\n\n---\n\n## 10. Approximation Guidelines\n\nWhen the source code uses an unsupported feature, follow these rules:\n\n1. **If a close approximation exists** (e.g., `alertcondition()` \u2192 `plotshape()`): Use the approximation AND warn the user about semantic differences\n2. **If the feature is cosmetic** (e.g., `log.info()`, `print()`): Remove it silently with an info-level warning\n3. **If the feature is functional** (e.g., `strategy.entry()`, `matrix.*`): Report it as unsupported and explain what was lost\n4. **If the feature is critical to the script's purpose** (e.g., strategy execution in a strategy script): Lower confidence to LOW and explain that the conversion is incomplete\n5. **Never invent functions** that don't exist in ForgeScript \u2014 this causes hallucination validation failures\n";
11
+ //# sourceMappingURL=knowledge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/server/knowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,qBAAqB,glLAsHjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,40sDA2nDjC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Agent System Prompt Builder
3
+ *
4
+ * Constructs the complete system prompt for the Anthropic Claude API,
5
+ * including role definition, core rules, ForgeScript reference, and chart context.
6
+ */
7
+ import type { ChartContextSnapshot } from '@forgecharts/types';
8
+ /**
9
+ * Builds the complete system prompt for the agent given the current chart context.
10
+ * Includes role definition, operational rules, ForgeScript reference, and context snapshot.
11
+ */
12
+ export declare function buildSystemPrompt(chartContext: ChartContextSnapshot): string;
13
+ //# sourceMappingURL=systemPrompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"systemPrompt.d.ts","sourceRoot":"","sources":["../../src/server/systemPrompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG/D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,oBAAoB,GAAG,MAAM,CAwN5E"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Agent Tool Definitions for Anthropic API
3
+ *
4
+ * This module exports all tool schemas that the agent can use. Tools are organized
5
+ * by category: Chart Navigation, Market Data, Indicators, Drawings, ForgeScript,
6
+ * Layout, Watchlist, and Trading (read-only).
7
+ */
8
+ interface ToolInput {
9
+ type: 'object';
10
+ properties: Record<string, unknown>;
11
+ required: string[];
12
+ }
13
+ interface Tool {
14
+ name: string;
15
+ description: string;
16
+ input_schema: ToolInput;
17
+ }
18
+ /**
19
+ * Gets the complete array of agent tool definitions in Anthropic API format.
20
+ * Each tool has a name, description, and input schema.
21
+ */
22
+ export declare function getAgentTools(): Tool[];
23
+ export {};
24
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,UAAU,SAAS;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,UAAU,IAAI;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,SAAS,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,IAAI,EAAE,CAqrBtC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgecharts/sdk",
3
- "version": "1.3.8",
3
+ "version": "1.3.10",
4
4
  "description": "ForgeCharts SDK — canvas-based charting engine, no third-party chart libraries",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,6 +34,11 @@
34
34
  "import": "./dist/react/internal.js",
35
35
  "require": "./dist/react/internal.js"
36
36
  },
37
+ "./server": {
38
+ "types": "./dist/server/index.d.ts",
39
+ "import": "./dist/server/index.js",
40
+ "require": "./dist/server/index.js"
41
+ },
37
42
  "./styles.css": "./dist/forgecharts.css"
38
43
  },
39
44
  "files": [