Skip to main content

Overview

Autonome supports multiple AI providers (OpenRouter, Nvidia NIM, AIHubMix) and strategy variants that implement distinct trading philosophies. Each variant has a custom system prompt and user prompt that shape the agent’s decision-making.

Apex

Geometric Growth Engine
High leverage (10x), volatility squeezes, profit ratcheting

Trendsurfer

Momentum Rider
ADX filtering, Ichimoku cloud breakouts, trailing stops

Contrarian

Mean Reversion Specialist
RSI extremes, oversold bounces, fixed targets

Sovereign

Risk-Adjusted Strategist
Kelly Criterion sizing, macro confluence, structured exits

Variant Configuration

Variants are defined in the shared configuration module:
// src/core/shared/variants/index.ts
export const VARIANT_IDS = ["Apex", "Trendsurfer", "Contrarian", "Sovereign"] as const;
export type VariantId = typeof VARIANT_IDS[number];

export const VARIANT_CONFIG: Record<VariantId, VariantConfig> = {
  Apex: {
    label: "Apex",
    description: "Geometric Growth Engine (10x leverage, squeezes)",
    color: "#f59e0b",
    badgeClasses: "bg-amber-500/10 text-amber-500",
  },
  // ...
};

AI Provider Setup

Autonome integrates three AI providers with API key rotation:
// src/server/features/trading/consensusOrchestrator.ts:136
function createProviders() {
  const nimApiKey = getNextNimApiKey();  // Rotating key pool
  const nim = createOpenAICompatible({
    name: "nim",
    baseURL: "https://integrate.api.nvidia.com/v1",
    headers: { Authorization: `Bearer ${nimApiKey}` },
  });

  const openrouter = createOpenRouter({
    apiKey: getNextOpenRouterApiKey(),
  });

  const aihubmix = createAihubmix({
    apiKey: getNextAihubmixApiKey(),
  });

  return { nim, openrouter, aihubmix };
}
Key Rotation:
  • Define multiple API keys in .env.local: NIM_API_KEY_1, NIM_API_KEY_2, …
  • getNextNimApiKey() cycles through keys using a round-robin counter
  • Prevents rate limits when running multiple parallel agents
See src/env.ts for rotator implementation.

Prompt Architecture

Each variant has two prompts:
  1. System Prompt: Static strategy rules, identity, tool usage guidelines
  2. User Prompt: Dynamic template with placeholders for market data and portfolio state

Example: Apex (High Leverage Aggressor)

// src/server/features/trading/prompts/apex.ts
export const SYSTEM_PROMPT = `You are **Autonome Apex**, a Geometric Growth Engine.

== IDENTITY: THE AGGRESSOR ==
- **Psychology:** You fear nothing but math. You bet heavily when Probability ($P$) > 60%.
- **Edge:** You trade **Volatility Squeezes** (Bollinger Bands inside Keltner).

== THE PROFIT RATCHET (CRITICAL) ==
You use 10x Leverage. This means gains vanish fast. You must **LOCK IT IN**.
1. **Breakeven:** If Unrealized PnL > 15% (1.5% price move), move Stop to Entry.
2. **Bank It:** If Unrealized PnL > 30% (3.0% price move), Trail Stop to lock 15%.
*Never let a +30% winner turn into a loser.*

== TOOL INTERFACE ==
Control portfolio via these tools (call directly):
- createPosition: Open new positions (leverage: 10x)
- closePosition: Exit positions
- updateExitPlan: Modify stops/targets
- holding: Explicit no-action (explain reasoning)
**Never output raw JSON or tool syntax as plain text.**

== OPERATIONAL CONSTRAINTS ==
- **Momentum Validation:**
   - **Longs:** Price MUST be > **VWAP**.
   - **Shorts:** Price MUST be < **VWAP**.
- **Execution:** If a Squeeze breaks out in the direction of VWAP, enter immediately.
- **Leverage:** 10x.
`;

export const USER_PROMPT = `
Session: {{TOTAL_MINUTES}} min | Interval: 5 min | Invocations: {{INVOKATION_TIMES}} | {{CURRENT_TIME}} IST
Cash: {{AVAILABLE_CASH}} | Exposure: {{EXPOSURE_TO_EQUITY_PCT}}%

== MARKET DATA ==
{{MARKET_INTELLIGENCE}}
*Focus on Volatility (Bollinger Squeezes) and VWAP.*

== PORTFOLIO ==
{{PORTFOLIO_SNAPSHOT}}

== OPEN POSITIONS ==
{{OPEN_POSITIONS_TABLE}}

== PERFORMANCE ==
{{PERFORMANCE_OVERVIEW}}

== MISSION ==
1. **Audit:** Check Open Positions. Apply "Profit Ratchet" if >15% ROE.
2. **Scan:** Find Squeezes + VWAP Confluence.
3. **Attack:** Execute with 10x.

CRITICAL: End your response with a tool call. If no action needed, call holding() with your reasoning.
`;

Example: Trendsurfer (Momentum Rider)

// src/server/features/trading/prompts/trendsurfer.ts
export const SYSTEM_PROMPT = `You are **Autonome Trendsurfer**. You are a Trend Follower.

== IDENTITY: RIDE THE WAVE ==
- **Philosophy:** Buy High, Sell Higher.
- **Filter:** You only trade when **ADX > 25**. (No Trend = No Trade).

== OPERATIONAL CONSTRAINTS ==
- **Entry:** Price must be above **Ichimoku Cloud** (Bullish) or below (Bearish).
- **Trigger:** Breakout of 20-period High.
- **Exit Strategy:** NEVER use fixed targets. Trail your stop loss using the **Kijun-Sen** (Base Line) or EMA20.

== DECISION FRAMEWORK ==
1. **Regime:** Is ADX > 25? Is Price > Cloud (for longs) or < Cloud (for shorts)?
2. **Action:** Enter Breakout.
3. **Manage:** Update Exit Plan to trail stop using Kijun-Sen.
`;
Trendsurfer uses no fixed profit targets—only trailing stops via updateExitPlan. This prevents premature exits in strong trends.

Data Source Hierarchy

All prompts enforce a critical data hierarchy:
  1. Manual/Exchange Indicators (Execution): Use for exact entry price, stop loss, and invalidation (orderbook-based)
  2. Taapi/Binance Indicators (Context): Use for broad trend and market regime (ADX, Supertrend, Ichimoku)
This prevents agents from using stale or misaligned indicators for trade execution.

Prompt Data Principles

Autonome follows strict spoon-feeding guidelines when building prompts:

Principle 1: Explicit Labels

Bad: risk $128.56 (ambiguous: USD or basis points?)
Good: risk_usd $128.56 (unambiguous)

Principle 2: Show Zeros

Bad: Omit scaled_realized if zero
Good: scaled_realized $0.00 (indicates no partial closes yet)

Principle 3: Omit N/A

Bad: funding_rate N/A (noise)
Good: Only show funding_rate if data exists

Principle 4: No Duplication

Each metric lives in exactly one section:
  • Session Header: invocationCount, currentTime, availableCash, exposurePct
  • PORTFOLIO: totalValue, unrealizedPnl, leverage, riskUsd
  • PERFORMANCE: sharpeRatio, winRate, maxDrawdown, closedTradeRealizedPnl
  • OPEN POSITIONS: Per-position entryPrice, markPrice, unrealizedPnl, roe

Principle 5: Clarity Over Brevity

Bad: SR (token-optimized)
Good: sharpe_ratio (explicit, no ambiguity)
Token cost is not a concern. Clarity and completeness are paramount. AI models are cheap; trading mistakes are expensive.

Prompt Builder Implementation

// src/server/features/trading/promptBuilder.ts:77
export function buildTradingPrompts(params: TradingPromptParams): {
  systemPrompt: string;
  userPrompt: string;
  variantId: VariantId;
  stateSummary: string;
} {
  const { variant = DEFAULT_VARIANT, portfolio, openPositions, exposureSummary } = params;

  // Get variant-specific prompts
  const variantConfig = getVariantConfig(variant);
  const SYSTEM_PROMPT = variantConfig.systemPrompt;
  const USER_PROMPT = variantConfig.userPrompt;

  // Replace placeholders with actual data
  const userPrompt = USER_PROMPT
    .replaceAll("{{INVOKATION_TIMES}}", account.invocationCount.toString())
    .replaceAll("{{CURRENT_TIME}}", currentTime)
    .replaceAll("{{AVAILABLE_CASH}}", formatUsd(portfolio.availableCash))
    .replaceAll("{{MARKET_INTELLIGENCE}}", marketIntelligence)
    .replaceAll("{{PORTFOLIO_SNAPSHOT}}", buildPortfolioSnapshotSection({...}))
    .replaceAll("{{PERFORMANCE_OVERVIEW}}", buildPerformanceOverview({...}));

  // Build compact state summary for prepareStep updates
  const stateSummary = buildStateSummary({ portfolio, openPositions, exposureSummary });

  return { systemPrompt: SYSTEM_PROMPT, userPrompt, variantId: variant, stateSummary };
}

Prompt Sections

Prompts are assembled from modular sections:
// src/server/features/trading/promptSections.ts (conceptual)
export function buildPortfolioSnapshotSection(params: {
  portfolio: PortfolioSnapshot;
  openPositions: EnrichedOpenPosition[];
  exposureSummary: ExposureSummary;
}): string {
  return `
total_value_usd $${portfolio.totalValue.toFixed(2)}
available_cash_usd $${portfolio.availableCash.toFixed(2)}
unrealized_pnl_usd $${portfolio.unrealizedPnl.toFixed(2)}
exposure_to_equity_pct ${exposureRatio.toFixed(1)}%
risk_to_equity_pct ${riskToEquityPct}%
`;
}

export function buildPerformanceOverview(params: {
  performanceMetrics: PerformanceMetrics;
}): string {
  return `
sharpe_ratio ${performanceMetrics.sharpeRatio}
win_rate ${performanceMetrics.winRate}
max_drawdown ${performanceMetrics.maxDrawdown}
closed_trade_realized_pnl_usd $${performanceMetrics.closedTradeRealizedPnl.toFixed(2)}
`;
}
Never calculate derived metrics in the prompt. Always compute them server-side and pass as explicit values.

Consensus Orchestrator

For enhanced decision quality, Autonome supports parallel consensus voting across multiple models:
// src/server/features/trading/consensusOrchestrator.ts:419
export async function runConsensusVoting(
  config: ConsensusConfig,
  marketIntelligence: string,
  portfolio: PortfolioSnapshot,
  openPositions: EnrichedOpenPosition[],
): Promise<ConsensusResult> {
  // Run all voters in parallel with timeout
  const voterPromises = config.voters.map((voter) =>
    Promise.race([
      getVoterDecision(voter, marketIntelligence, portfolio, openPositions),
      new Promise((_, reject) =>
        setTimeout(() => reject(new Error(`Timeout`)), config.timeoutMs),
      ),
    ]),
  );

  const results = await Promise.all(voterPromises);
  return aggregateVotes(results, config);
}
Consensus Pattern:
  1. Run 3+ models in parallel with same market data
  2. Aggregate decisions via weighted voting
  3. Only execute trades where 2/3+ models agree with confidence >= 6/10
Benefits:
  • Reduces single-model bias
  • Higher confidence trades
  • Exploits diverse reasoning styles
See src/server/features/trading/consensusOrchestrator.ts for full implementation.

Model Configuration

// src/core/shared/models/modelConfig.ts (conceptual)
export interface ModelConfig {
  id: string;
  name: string;
  openRouterModelName: string;
  provider: "openrouter" | "nim" | "aihubmix";
  variant: VariantId;
  maxTokens?: number;
  temperature?: number;
}

export const DEFAULT_MODELS: ModelConfig[] = [
  {
    id: "deepseek-r1-apex",
    name: "DeepSeek R1",
    openRouterModelName: "deepseek-ai/deepseek-r1",
    provider: "openrouter",
    variant: "Apex",
  },
  {
    id: "llama-3-70b-trendsurfer",
    name: "Llama 3 70B",
    openRouterModelName: "meta-llama/llama-3-70b-instruct",
    provider: "nim",
    variant: "Trendsurfer",
  },
];

Autonomous Trading Loop

Learn how agents execute the full trading workflow

Configuration

Set up API keys and model providers

Strategy Variants

Explore the different AI trading strategies

Trading System

Understand the trading system architecture

Build docs developers (and LLMs) love