Hawk-Backtester with AI Agent Mode

Agent Mode API Manual

A reference for your AI Agent to run the autonomous loop of strategy generation -> backtesting -> evaluation -> improvement using this system's API.

Concept»

Your AI Agent autonomously cycles through "strategy generation -> execution -> evaluation -> improvement."
* The AI Agent is provided and contracted by you; it is not included in this service.

1Strategy Code Generation
Based on data features,
generate a hawk-bt Strategy
AI Agent
2Run Backtest & View Results
hawk-bt -> WASM
auto-execute the STEP_NEXT loop
AI Agent
API
4Improve Strategy
Based on evaluation results,
modify parameters / logic
AI Agent
3Evaluate Results
return, DD, profit factor, etc.
assess and identify improvement areas
AI Agent

Quick Start»

pip install hawk-bt

* hawk-backtester on PyPI is a separate, unrelated package.

  1. サービスログイン後、with AI Agent タブをクリック
  2. Enable Agent Mode
  3. Agent Dashboard をブラウザで開いたままにする
  4. Execute instructions like the following to your AI Agent:

How It Works

The WASM simulation engine runs in the browser. After the Agent starts HawkEngine and registers a session via POST /v1/backtests, the Agent Dashboard automatically detects it and handles simulation -> analysis -> saving in one flow.

  1. Agent starts the WebSocket server in the background with engine.start_background(strategy) and waits with engine.wait_ready()
  2. Agent sends POST /v1/backtests (session registration + ws_url specification)
  3. Agent Dashboard (browser) automatically detects the session, starts the WASM engine, and establishes the WS connection
  4. After simulation completes, the browser automatically computes all analysis data (resultStats, ticketTraces + MFE/MAE, time series data) and saves it to the server
  5. Agent retrieves comprehensive analysis data via GET /v1/backtests/{id}/results
  • Agent Dashboard must be kept open — it serves as the WASM execution environment
  • No manual operation required — the browser detects QUEUED sessions every 3 seconds and starts them automatically
  • Must run on the same machine — the browser and Agent must operate on the same machine (ws://127.0.0.1:8787)
# ── Instruction Template for Your AI Agent ── You are an agent that autonomously develops and improves trading strategies. ## Reference Documents Please read the following 2 documents in advance. 1. Agent Mode API Manual … REST/WS specifications, Analysis Data structure https://app.hawk-backtester.com/agent-manual/ 2. hawk-bt Reference … How to write a Strategy class, HawkEngine configuration https://app.hawk-backtester.com/py-engine/ ## Steps 1. Strategy Code Generation Inherit the hawk-bt Strategy class and implement logic in async def step(ctx). Aim for strategies that win generally without overfitting to specific data. 2. Dataset Selection Retrieve the dataset list with GET /v1/data/datasets, and check features (volatility, trend_strength, regime_hint, etc.) with GET /v1/data/features. Select a dataset suitable for strategy validation. 3. Run Backtest Start hawk-bt's HawkEngine in the background, and register a session via POST /v1/backtests after engine.wait_ready(). Wait for simulation completion with thread.join() and retrieve the results. 4. Result Evaluation analysis.outcome (totalReturn, maxDrawdown, returnOverMaxDD), analysis.attribution (profitFactor, winRate), Evaluate analysis.action (totalOrders, medianHoldingTime) comprehensively. Prioritize risk-adjusted returns rather than a single metric. 5. Strategy Improvement Identify specific improvements from evaluation results and modify the strategy code. Return to Step 3 and repeat the improvement loop. 6. Save Once target levels are achieved, save via POST /v1/backtests/{session_id}/save. ## Constraints - Record the intent of changes in strategy_note for each iteration

Security»

API Key

  • This is displayed only once upon generation. Be sure to copy and store it securely.
  • Valid for 90 days. After expiration, please regenerate from the Dashboard.
  • Revoking immediately invalidates the key.

Rate Limits

  • API requests: 300 per minute (IP-based)
  • Authentication failures: 10 failures from the same IP result in a 15-minute lockout.

WebSocket Connection

  • hawk-bt's WS server binds to 127.0.0.1:8787. It is not exposed to external networks.
  • Origin header validation is performed on connection; connections from origins not on the allow list are rejected with 403 Forbidden.
  • The Agent and browser must be running on the same machine.

API Reference»

Base URL: https://app.hawk-backtester.com/v1/

Data API

GET /v1/data/datasets

Dataset list (with summary_stats and regime_hint)

Response

{ "datasets": [{ "dataset_id": 123, "symbol": "EURUSD", "timeframe": "1H", "rows": 5000, "summary_stats": { "mean": 1.0892, "volatility": 0.0045, "hurst_exponent": 0.52, "trend_strength": 0.65, ... }, "regime_hint": "trend" }] }
GET /v1/data/datasets/{id}

Dataset details

Response

{ "dataset_id": 123, "symbol": "EURUSD", "name": "EURUSD_1H_2024", "timeframe": "1H", "rows": 5000, "file_path": "ohlc/eurusd_1h.csv", "close_series": [1.0892, 1.0895, ...] // optional: max 2000points downsampled }
GET /v1/data/features?dataset_id=123

Feature list (with category classification)

Response

{ "features": [{ "dataset_id": 123, "target_type": "close", "features": { "volatility": { "value": 0.0045, "category": "volatility" }, ... } }] }

Backtest API

POST /v1/backtests

Session registration + auto-start signal

The browser (Agent Dashboard) automatically detects QUEUED sessions and starts the simulation.

Request

{ "dataset_id": 123, "iteration": 1, "strategy_note": "RSI(14) + SMA crossover, SL=2%", "seed": 42, "ws_url": "ws://127.0.0.1:8787", // HawkEngine WS address (default if omitted) "config": { "leverage": 25, "initial_assets": 10000, "start_step": 0, // 開始ステップ (省略可) "end_step": 50000 // 終了ステップ (省略可) } }

Response (201)

{ "session_id": "550e8400-...", "status": "queued" }
GET /v1/backtests/{session_id}/results

Retrieve results (recommended) — get comprehensive analysis data saved by the browser

The browser automatically computes and saves all analysis data (outcome, attribution, ticketTraces, timeSeries, etc.) after simulation completes.
After the Agent detects simulation completion via on_result, retrieve results from this endpoint.

Response

{ "session_id": "...", "status": "succeeded", "analysis": { "outcome": { ... }, // → Analysis Data Format "exposure": { ... }, "attribution": { ... }, "action": { ... }, "ticketTraces": [ ... ], // Trade details with MFE/MAE "timeSeries": { ... }, // equity, drawdown, exposure etc. (max 2000points) "totalSteps": 5000, "initialAssets": 10000 } }
POST /v1/backtests/{session_id}/save

Fully save session as SimulationResult

Request

FieldTypeRequiredDescription
titlestring-Save title (default: Agent #N: strategy_note)
memostring-Memo (default: strategy_note)
strategy_namestring-Strategy name (e.g., "SMA_Crossover_v2")
{ "title": "Best Strategy #3", "memo": "PF 1.8, DD -3.2%", "strategy_name": "SMA_Crossover_v2" }
Dataset is automatically inherited from the dataset_id specified at session creation.
Leverage is automatically saved from config.leverage specified at session creation.
There is no need to change these — set them correctly in POST /v1/backtests.

Response

{ "result_id": "a1b2c3d4-..." }

Status API

GET /v1/agent/status

Agent Mode status + recent sessions

GET /v1/agent/dashboard-data?limit=30

Dashboard timeline (max 50)

WebSocket Protocol»

All WS communication (INIT, STEP_NEXT, orders, result reception) is automatically handled by hawk-bt.
The Agent only needs to be aware of the following 2 points.

Config

Simulation settings are applied to WASM from the browser side (Agent Dashboard).
Can be specified in the config field of POST /v1/backtests.

FieldTypeDefaultDescription
leveragefloat0Leverage multiplier (0 = unlimited)
commissionfloat0Commission rate per order
ticketLimitMarginfloat0Required margin ratio
maxTicketLimitsint0Max concurrent positions (0 = unlimited)
start_stepint0シミュレーション開始ステップ (0 = 先頭から)
end_stepint(全バー)シミュレーション終了ステップ (未指定 = 最後まで)

HawkEngine: single_run Mode

⚠ CRITICAL
Agent Mode では single_run=True を必ず指定してください。
指定しない場合、シミュレーション完了後もプロセスが永久にハングし、Agent の自律ループが停止します。
single_run=True を指定すると、1 回のシミュレーション完了後にプロセスが自動終了し、次のイテレーションへ進めます。
engine = HawkEngine( host="127.0.0.1", port=8787, single_run=True, # Agent Mode: Exit after one run on_result=my_callback, ) # Background start -> session registration -> wait for completion thread = engine.start_background(strategy) engine.wait_ready() # Wait for WS server to start resp = requests.post(...) # Register session via POST /v1/backtests if resp.status_code != 201: raise RuntimeError(resp.text) # Exit immediately on error (don't call thread.join()) thread.join() # Wait for simulation to complete

Analysis Result

After simulation completes, the browser automatically computes all analysis data and saves it to the server.

  1. Receive BacktestResult (balance/equity arrays) via hawk-bt's on_result callback
  2. Simultaneously, the browser computes resultStats, ticketTraces (with MFE/MAE), and time series data (equity, drawdown, exposure, etc.)
  3. The browser saves comprehensive analysis data to the server via POST /v1/backtests/report
  4. Agent can retrieve all data via GET /v1/backtests/{session_id}/results

詳細な分析データは Analysis Data Format を参照。

Analysis Data Format»

Analysis result JSON received after simulation completes.

outcome

FieldTypeNote
totalStepsintTotal Steps
endingAssetsfloatFinal Cash
endingEquityfloatFinal Equity
totalReturnfloat0.075 = 7.5%
maxDrawdownfloatNegative value
returnOverMaxDDfloatReturn / Max DD
vsBuyHoldfloatDifference vs. B&H

exposure

FieldTypeNote
avgGrossExposurefloatAverage Gross Exposure
maxGrossExposurefloatMax Gross Exposure
avgNetExposurefloatAverage Net Exposure
timeInMarketfloatTime in Position Ratio
longRatiofloatLong Ratio
shortRatiofloatShort Ratio
exposureEfficiencyfloattotalReturn / avgGrossExposure

attribution

FieldTypeNote
longPnLfloatCumulative Long PnL
shortPnLfloatCumulative Short PnL
costPnLfloatTotal Trading Costs
totalPnLfloatlongPnL + shortPnL + costPnL
longContribfloatlongPnL / totalPnL
shortContribfloatshortPnL / totalPnL
costContribfloatcostPnL / totalPnL
profitFactorfloatGross Profit / Gross Loss
costBurdenfloat|costPnL| / |longPnL + shortPnL|
winRatefloat0.58 = 58%
winCountintWinning Trades
lossCountintLosing Trades
totalTicketsintwinCount + lossCount

action

FieldTypeNote
totalOrdersintTotal Orders
buyCountintBuy Orders
sellCountintSell Orders
buySellRatiofloatbuyCount / (buyCount + sellCount)
ordersPer1000floatOrders per 1000 Steps
medianHoldingTimefloatMedian Holding Time (ms)
p90HoldingTimefloat90th Percentile Holding Time (ms)
medianTicketSizefloatMedian Trade Size
partialCloseCountintPartial Close Count

ticketTraces

Details of each trade + MFE/MAE (Max Favorable/Adverse Excursion).

FieldTypeNote
ticketIdintTicket ID
sidestring"long" or "short"
entryTimefloatEntry Time (ms)
exitTimefloatExit Time (ms)
entryPricefloatEntry Price
exitPricefloatExit Price
unitsfloatTrade Size
lifetimefloatHolding Time (exitTime - entryTime)
exitReasonint0=SL, 1=TP, 2=Strategy, 5=Force
pnlfloatPnL (units * price diff)
pnlPctfloatPnL Rate (%)
mfefloatMax Favorable Excursion (amount)
maefloatMax Adverse Excursion (amount)

timeSeries

Time series data (downsampled to max 2000 points).

FieldTypeNote
timestampsfloat[]Timestamp (ms)
equityfloat[]Equity (including unrealized PnL)
assetsfloat[]Cash Balance
buyAndHoldfloat[]Buy & Hold Comparison Curve
drawdownfloat[]Drawdown (negative value)
netExposurefloat[]Net Exposure
grossExposurefloat[]Gross Exposure
marginRatiofloat[]Margin Usage Ratio
cumulativeLongPnLfloat[]Cumulative Long PnL
cumulativeShortPnLfloat[]Cumulative Short PnL
ticketLongCountfloat[]Cumulative Long Ticket Count
ticketShortCountfloat[]Cumulative Short Ticket Count
tokenLongCountfloat[]Cumulative Long Token Count
tokenShortCountfloat[]Cumulative Short Token Count

totalSteps / initialAssets

"totalSteps": 5000, // Total number of simulation steps "initialAssets": 10000 // Initial Capital

Example Code»

Below are code examples corresponding to each step of the Concept.
Your AI Agent executes these in order and runs the loop autonomously.

Step 1 — Strategy Code Generation

# Define a strategy by inheriting hawk-bt's Strategy class from hawk_bt import Strategy, Context from collections import deque class MyStrategy(Strategy): def __init__(self): self.prices = deque(maxlen=50) def _sma(self, n): if len(self.prices) < n: return None return sum(list(self.prices)[-n:]) / n async def step(self, ctx: Context): s = ctx.state.snapshot self.prices.append(s.price) fast = self._sma(20) slow = self._sma(50) if fast is None or slow is None: return if fast > slow and s.tickets_num == 0: await ctx.engine.place_ticket( side="buy", units=10, take_profit=5.0, stop_loss=3.0, )

Step 2 — Dataset Selection & Backtest Execution

import requests, time from hawk_bt import HawkEngine, configure_logging # Log output settings (optional): 1=WARNING, 2=INFO (default), 3=DEBUG configure_logging(verbosity=2) API = "https://app.hawk-backtester.com/v1" AUTH = {"Authorization": "Bearer hawk_YOUR_KEY"} # Dataset Selection ds = requests.get(f"{API}/data/datasets", headers=AUTH).json() ds_id = ds["datasets"][0]["dataset_id"] # 1. Start the engine in the background (start the WS server first) engine = HawkEngine( host="127.0.0.1", port=8787, single_run=True, ) thread = engine.start_background(MyStrategy()) engine.wait_ready() # Wait for WS server startup to complete # 2. Register session resp = requests.post(f"{API}/backtests", headers=AUTH, json={ "dataset_id": ds_id, "iteration": 1, "strategy_note": "SMA crossover 20/50", "ws_url": "ws://127.0.0.1:8787", "config": {"leverage": 25, "initial_assets": 10000}, }) if resp.status_code != 201: raise RuntimeError(f"POST /backtests failed: {resp.text}") sid = resp.json()["session_id"] # 3. Wait for simulation to complete thread.join() # Wait briefly for the browser to save analysis data time.sleep(2) # Retrieve results — the browser has auto-computed and saved all analysis data result = requests.get( f"{API}/backtests/{sid}/results", headers=AUTH ).json() analysis = result["analysis"]

Step 3 — Evaluate Results

# Summary Metrics print(f"Return: {analysis['outcome']['totalReturn']:.2%}") print(f"Max Drawdown: {analysis['outcome']['maxDrawdown']:.2%}") print(f"Profit Factor: {analysis['attribution']['profitFactor']}") print(f"Win Rate: {analysis['attribution']['winRate']}") print(f"Total Orders: {analysis['action']['totalOrders']}") # Trade Details (with MFE/MAE) for t in analysis.get("ticketTraces", [])[:5]: print(f" {t['side']} pnl={t['pnl']:.2f} ({t['pnlPct']:.1f}%) MFE={t['mfe']:.2f} MAE={t['mae']:.2f}") # Time Series Data (equity, drawdown, exposure, etc.) ts = analysis.get("timeSeries", {}) print(f"Time series points: {len(ts.get('equity', []))}") print(f"Final equity: {ts['equity'][-1]:.2f}") print(f"Final B&H: {ts['buyAndHold'][-1]:.2f}") print(f"Min drawdown: {min(ts['drawdown']):.2%}")

Step 4 — Improve / Save Strategy

# Goal achieved — Save # dataset_id and leverage are automatically saved with the values from session creation requests.post( f"{API}/backtests/{sid}/save", headers=AUTH, json={ "title": "SMA crossover v1", "memo": "PF 1.8, DD -3.2%", "strategy_name": "SMA_Crossover", // Strategy name (optional) } ) # Not achieved — Modify strategy code based on evaluation results and return to Step 2