Skip to Content
AgentsAgent Workflow Guide

Agent workflow

This is the current workflow for an authenticated agent using Lona’s MCP tools. It covers authoring, validation, dry-running, saving, backtesting, optimization, and report analysis.

Workflow at a glance

StepTool or actionResult
1lona_get_strategy_documentationLoad the authoritative Backtrader execution rules
2Author complete Python sourceInclude strategy parameters, data handling, orders, and risk rules
3lona_run_dry_run_backtestValidate the unsaved source and fix errors
4lona_create_strategySave the validated strategy and retain its returned id
5lona_search_symbols_by_name or lona_list_symbolsSelect real symbol IDs and inspect frequency availability
6lona_get_market_data_sampleInspect OHLCV values when needed
7lona_run_backtestSubmit one asynchronous historical execution
8lona_wait_for_reportsPoll with report_ids until terminal status
9lona_get_report and lona_list_report_tradesAnalyze summary, symbols, diagnostics, and paged trades
10lona_run_optimization (optional)Sweep one or two numeric parameters with approval
11lona_wait_for_optimization and lona_list_optimization_resultsWait and inspect historical optimization runs

The MCP server does not expose asynchronous AI strategy generation or a separate code-view tool. Use the registered authoring, dry-run, create, and get-strategy tools documented here.

1. Load the authoring contract

Call lona_get_strategy_documentation with {} before writing or changing strategy code. The returned document is the source of truth for the Backtrader runtime. In particular, it defines the available bt APIs, the required multi-data behavior, parameter format, order lifecycle, and visualization rules.

Do not add imports to the submitted source. Define a class inheriting from bt.Strategy, use tuple-form parameters, initialize indicators in __init__, and put trading decisions in next(). When multiple feeds are used, handle self.datas consistently and keep indicators and active orders associated with the appropriate data feed.

2. Author and validate code

Write the complete source from the user’s requirements. Include explicit entry/exit logic, position sizing, stop-loss or take-profit behavior where requested, and the intended timeframe/data assumptions.

Before saving, call:

{ "code": "class Strategy(bt.Strategy):\n params = ((\"period\", 20),)\n ..." }

with lona_run_dry_run_backtest. This checks the actual unsaved source in the execution environment. Fix every returned validation or execution error and repeat the dry run with the full corrected source. A successful dry run is the validation gate; it does not create a saved strategy or a historical report.

3. Save or update the strategy

After the dry run succeeds, call lona_create_strategy:

{ "name": "RSI Momentum", "description": "Buys on an RSI recovery and exits on a momentum reversal.", "code": "...complete validated source...", "version": "1.0.0" }

Save the returned strategy id; it is required by later backtests and optimizations. If the strategy already exists, use lona_update_strategy with the current id. Updating creates a new immutable version. When updating code, repeat the documentation and dry-run steps against the complete new source.

The create and update tools do not generate code, run an AI review, or accept a description in place of Python. If you need gateway AI generation, use the separate routes described in MCP Tools Reference.

4. Choose data

Use lona_search_symbols_by_name when you know a ticker or name, or lona_list_symbols when browsing. Both return IDs that can be passed to a backtest. Do not invent IDs.

Global symbols are shared pre-loaded data. If the required global symbol is not present, lona_download_market_data requests full-history OHLCV data from the Tiingo-backed service and caches it globally. Existing global data is reused. The MCP server has no market-data upload tool; user-uploaded symbols, when available in the account, are discovered through the symbol tools.

Global frequency rules are:

  • Equities and ETFs are daily-only (1d).
  • Forex, metal pairs such as XAU/USD, and crypto support 5m, 15m, 1h, 4h, and 1d.
  • lona_download_market_data defaults asset_class to equity, so specify forex or crypto for intraday requests.

Use lona_get_symbol or the data_availability returned by the list/search tools to confirm the range and frequency. Use lona_get_market_data_sample only when inspecting actual candle values is useful; its default is 50 points and its hard maximum is 10,000.

Example search:

{"symbolName": "AAPL"}

Example download:

{ "symbol": "EUR/USD", "frequency": "1h", "asset_class": "forex" }

5. Submit a backtest

Call lona_run_backtest only after the strategy is saved and the symbol IDs and common frequency are known:

{ "strategy_id": "strategy-id", "data_ids": ["symbol-id"], "frequency": "1d", "start_date": "2024-01-01", "end_date": "2024-12-31", "initial_cash": 100000, "commission": 0, "leverage": 1, "buy_on_close": false }

Required dates are YYYY-MM-DD. The selected frequency must be present for every data source. Optional parameters is an array of { name, value } where the value is a number or boolean. The server defaults are initial_cash: 100000, commission: 0, leverage: 1, and buy_on_close: false.

The tool returns a snake_case report_id and starts an asynchronous execution. Statuses are PENDING, EXECUTING, COMPLETED, or FAILED.

6. Wait for reports correctly

Pass one or more report IDs using the plural report_ids field:

{"report_ids": ["report-id"]}

For multiple submitted runs:

{"report_ids": ["report-id-1", "report-id-2"]}

lona_wait_for_reports returns terminal results with report_id and status. Do not send { "id": "..." }; that was an obsolete contract. If a report fails, inspect it with lona_get_report for its error and diagnostics before retrying.

7. Analyze the report

Call lona_get_report with the report ID after completion. It returns summary metrics, recent reconstructed trades, per-symbol performance, diagnostics, and chart data when available. Stored report statistics are authoritative. Trade reconstruction is gross of commissions and fees and may not exactly match the stored trade count or win rate.

For the complete available trade history, page with lona_list_report_trades:

{ "id": "report-id", "skip": 0, "limit": 50 }

Continue while has_next is true. A single report response only includes a recent subset of reconstructed trades.

Useful stored statistics include final_portfolio_value, realized_pnl, total_return, maximum_drawdown_percentage, number_of_trades, open_trades, percentage_of_winning_trades, annualized_sharpe_ratio, cagr, profit_factor, payoff_ratio, expectancy, average_trade, recovery_factor, calmar_ratio, std_dev_returns, annualized_volatility, avg_bars_held, beta, alpha, sortino_ratio, and information_ratio.

8. Run an optimization when needed

Use optimization for a parameter sweep; do not submit a batch of individual backtests. The strategy must be saved first. lona_run_optimization accepts one or two numeric grids and fixed parameters for everything else.

Example:

{ "strategy_id": "strategy-id", "name": "RSI period sweep", "data_ids": ["symbol-id"], "frequency": "1d", "start_date": "2024-01-01", "end_date": "2024-12-31", "grids": [ { "name": "period", "min": 10, "max": 30, "step": 5 } ], "parameters": [], "simulation_parameters": { "initial_cash": 100000, "commission_schema": { "commission": 0, "leverage": 1 }, "buy_on_close": false }, "target_metric": "total_return", "target_direction": "maximize", "additional_metrics": [], "use_free_optimization": false }

Starting an optimization consumes a free entitlement or credits and requires explicit user approval. use_free_optimization is false by default and should be set true only when the user explicitly asks for the free entitlement.

Use lona_wait_for_optimization with the returned optimization_id, then lona_list_optimization_results to page through historical runs. Results are not recommendations: describe the target metric, direction, and observed values, and do not infer a “best” combination from summary payloads.

If the user explicitly asks to stop an active optimization, confirm and call lona_cancel_optimization.

Model and provider facts

The gateway supports these providers when configured with their credentials:

ProviderDefault conversion/validation modelDefault explanation model
anthropicclaude-sonnet-4-6claude-haiku-4-5-20251001
openaigpt-5.6-lunagpt-5.6-luna
xaigrok-4-1-fast-reasoninggrok-4-1-fast-non-reasoning
googlegemini-3-pro-previewgemini-2.5-flash
openroutermoonshotai/kimi-k2.5moonshotai/kimi-k2.5
azuregpt-5-4gpt-5-4

The configured DEFAULT_AI_PROVIDER defaults to anthropic. A caller can override provider and model on the gateway interview and generation routes. The /strategy/generate and /strategy/create routes run structural validation and AI review; their validation provider prefers Azure GPT-5.4 when both Azure credentials are configured, otherwise Anthropic Sonnet 4.6. Runtime provider failures may follow the configured fallback chain.

These provider settings apply to gateway AI routes. The registered MCP strategy tools do not accept provider or model fields because they expect the calling agent to author and validate source itself.

Last updated on