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
| Step | Tool or action | Result |
|---|---|---|
| 1 | lona_get_strategy_documentation | Load the authoritative Backtrader execution rules |
| 2 | Author complete Python source | Include strategy parameters, data handling, orders, and risk rules |
| 3 | lona_run_dry_run_backtest | Validate the unsaved source and fix errors |
| 4 | lona_create_strategy | Save the validated strategy and retain its returned id |
| 5 | lona_search_symbols_by_name or lona_list_symbols | Select real symbol IDs and inspect frequency availability |
| 6 | lona_get_market_data_sample | Inspect OHLCV values when needed |
| 7 | lona_run_backtest | Submit one asynchronous historical execution |
| 8 | lona_wait_for_reports | Poll with report_ids until terminal status |
| 9 | lona_get_report and lona_list_report_trades | Analyze summary, symbols, diagnostics, and paged trades |
| 10 | lona_run_optimization (optional) | Sweep one or two numeric parameters with approval |
| 11 | lona_wait_for_optimization and lona_list_optimization_results | Wait 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 support5m,15m,1h,4h, and1d. lona_download_market_datadefaultsasset_classtoequity, so specifyforexorcryptofor 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:
| Provider | Default conversion/validation model | Default explanation model |
|---|---|---|
anthropic | claude-sonnet-4-6 | claude-haiku-4-5-20251001 |
openai | gpt-5.6-luna | gpt-5.6-luna |
xai | grok-4-1-fast-reasoning | grok-4-1-fast-non-reasoning |
google | gemini-3-pro-preview | gemini-2.5-flash |
openrouter | moonshotai/kimi-k2.5 | moonshotai/kimi-k2.5 |
azure | gpt-5-4 | gpt-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.