Skip to main content
MindStudio
Pricing
Blog About
My Workspace

How to Build a 24/7 AI Trading Agent with Claude Code Routines

Use Claude Code routines and the Alpaca API to build an autonomous trading agent that researches markets, places trades, and journals results around the clock.

MindStudio Team RSS
How to Build a 24/7 AI Trading Agent with Claude Code Routines

What This Agent Actually Does

Most “AI trading bots” are glorified rule sets. They check a price threshold, fire an order, log a result. There’s no reasoning happening. Claude Code Routines let you build something different: an agent that researches market conditions, forms a view, decides whether to act, places a trade through the Alpaca API, and then writes a structured journal entry explaining its own reasoning — all without you touching a keyboard.

This guide walks through the full build. By the end, you’ll have a Claude Code trading agent that runs on a schedule, makes decisions autonomously, and keeps a structured log you can actually learn from.

A quick disclaimer before we start: this is a technical walkthrough for educational purposes. Nothing here constitutes financial advice. Start with Alpaca’s paper trading environment and understand what you’re building before putting real capital anywhere near it.


Prerequisites and What You’ll Need

Before writing a line of code, get these in order:

Accounts and API keys:

  • An Alpaca account (free; paper trading requires no real money)
  • An Anthropic API key with access to Claude
  • A server or cloud instance that stays online — a local laptop won’t cut it for 24/7 operation

Local environment:

  • Node.js 20+ or Python 3.11+
  • Claude Code installed and authenticated
  • Basic familiarity with how Claude Code runs tasks

Optional but useful:

  • A news API key (Newsapi.org, Polygon.io, or similar) for real-time sentiment data
  • A SQLite setup for journaling trade results locally

If you haven’t set up Claude Code Routines before, the overview on Claude Code scheduled tasks and routines is a good place to get oriented. Routines are Claude Code’s built-in mechanism for running agent workflows on a schedule — no external cron infrastructure needed.


Architecture Overview

The trading agent has four distinct skills running in sequence on each cycle:

  1. Market Research — Fetches price data, news headlines, and technical indicators for a watchlist of tickers
  2. Signal Generation — Claude analyzes the data and decides whether conditions warrant a trade
  3. Order Execution — If Claude decides to act, it calls the Alpaca API to place a market or limit order
  4. Trade Journal — Regardless of whether a trade was placed, Claude writes a structured log entry explaining its reasoning

Each cycle runs as a Claude Code Routine triggered on a fixed schedule. The agent doesn’t need to run every minute. For most strategies, a cycle every 15–30 minutes during market hours is plenty — and the journal gives you a full audit trail of every decision.

This is an example of what agentic workflows with conditional logic and branching look like in practice: not a straight pipeline, but a system that reasons before it acts.


Step 1: Set Up Your Alpaca Connection

Alpaca provides a REST API for stock and crypto trading. Paper trading (simulated) uses a separate base URL from live trading. Always start with paper.

Create a file called alpaca.js (or alpaca.py if you prefer Python):

// alpaca.js
const ALPACA_BASE_URL = 'https://paper-api.alpaca.markets'; // switch to live-api for real trading
const ALPACA_KEY = process.env.ALPACA_API_KEY;
const ALPACA_SECRET = process.env.ALPACA_API_SECRET;

async function getAccount() {
  const res = await fetch(`${ALPACA_BASE_URL}/v2/account`, {
    headers: {
      'APCA-API-KEY-ID': ALPACA_KEY,
      'APCA-API-SECRET-KEY': ALPACA_SECRET,
    },
  });
  return res.json();
}

async function getLatestQuote(symbol) {
  const res = await fetch(
    `https://data.alpaca.markets/v2/stocks/${symbol}/quotes/latest`,
    {
      headers: {
        'APCA-API-KEY-ID': ALPACA_KEY,
        'APCA-API-SECRET-KEY': ALPACA_SECRET,
      },
    }
  );
  return res.json();
}

async function placeOrder({ symbol, qty, side, type = 'market', timeInForce = 'day' }) {
  const res = await fetch(`${ALPACA_BASE_URL}/v2/orders`, {
    method: 'POST',
    headers: {
      'APCA-API-KEY-ID': ALPACA_KEY,
      'APCA-API-SECRET-KEY': ALPACA_SECRET,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ symbol, qty, side, type, time_in_force: timeInForce }),
  });
  return res.json();
}

module.exports = { getAccount, getLatestQuote, placeOrder };

Store your keys as environment variables, never hardcode them. Claude Code can read environment variables from your shell or a .env file at the project root.


Step 2: Build the Market Research Skill

The research skill pulls together the data Claude needs to form a view. Keep it focused — too much data and the model gets noisy, too little and it can’t reason well.

For each ticker on your watchlist, the research skill should collect:

  • Current price and recent OHLCV (open, high, low, close, volume) — Alpaca’s data API covers this
  • Recent news headlines — Polygon.io’s news endpoint or Newsapi.org work well
  • Simple technical signals — RSI, moving average crossover, or VWAP deviation (compute these locally from historical data)
  • Current positions — what does the agent already hold?

Create research.js to aggregate this. The output should be a clean JSON object Claude can read in a single context window. Something like:

{
  "timestamp": "2026-04-17T09:30:00Z",
  "account": {
    "buying_power": 8450.00,
    "portfolio_value": 10120.00
  },
  "watchlist": [
    {
      "symbol": "NVDA",
      "price": 876.45,
      "change_pct_1d": 1.8,
      "rsi_14": 62.3,
      "above_20ma": true,
      "recent_headlines": [
        "NVIDIA data center revenue beats estimates for Q1",
        "Analysts raise price targets following GPU demand outlook"
      ],
      "current_position": null
    }
  ]
}

Claude will read this JSON, reason about it, and output a structured decision. The cleaner the input format, the more reliable the output.

For a deeper look at how AI agents handle research and analysis tasks, the patterns there apply directly to this kind of market data pipeline.


Step 3: Write the Claude Decision Prompt

This is where the actual intelligence lives. The prompt instructs Claude to act as a disciplined trading agent with explicit constraints.

Create a file called system_prompt.md:

You are a disciplined algorithmic trading agent. Your job is to analyze market data and decide whether to place a trade.

Rules you must follow:
- Never risk more than 2% of total portfolio value on a single trade
- Do not trade if RSI is above 70 (overbought) or below 30 (oversold) unless you have a strong contrarian reason
- Only trade during regular market hours (9:30 AM - 4:00 PM ET)
- If you're uncertain, the default action is NO_TRADE
- Always explain your reasoning in plain language

Your output must be valid JSON in this exact format:
{
  "decision": "BUY" | "SELL" | "NO_TRADE",
  "symbol": "TICKER or null",
  "qty": number or null,
  "reasoning": "2-3 sentence explanation",
  "confidence": "LOW" | "MEDIUM" | "HIGH"
}

Then in your main agent script, call Claude with the research JSON appended to this system prompt. Using the Anthropic SDK:

const Anthropic = require('@anthropic-ai/sdk');
const client = new Anthropic();

async function getTradeDecision(marketData) {
  const systemPrompt = fs.readFileSync('./system_prompt.md', 'utf8');
  
  const message = await client.messages.create({
    model: 'claude-opus-4-5',
    max_tokens: 1024,
    system: systemPrompt,
    messages: [
      {
        role: 'user',
        content: `Here is the current market data. Analyze it and output your trade decision as JSON:\n\n${JSON.stringify(marketData, null, 2)}`
      }
    ]
  });
  
  const responseText = message.content[0].text;
  return JSON.parse(responseText);
}

The structured JSON output is important. It makes the response machine-readable so the next step can act on it without additional parsing logic.


Step 4: Execute the Trade

Once you have Claude’s decision, execution is straightforward:

async function executeDecision(decision) {
  if (decision.decision === 'NO_TRADE') {
    console.log('No trade placed:', decision.reasoning);
    return null;
  }

  if (decision.confidence === 'LOW') {
    console.log('Skipping low-confidence signal:', decision.reasoning);
    return null;
  }

  const order = await placeOrder({
    symbol: decision.symbol,
    qty: decision.qty,
    side: decision.decision.toLowerCase(), // 'buy' or 'sell'
    type: 'market',
    timeInForce: 'day',
  });

  console.log('Order placed:', order);
  return order;
}

Add a check for market hours before calling this. Alpaca will reject orders outside of trading hours anyway, but it’s cleaner to handle this in your code so the journal entry reflects the right reason.


Step 5: Write the Trade Journal

The journal is what separates a learning system from a black box. After every cycle — whether or not a trade was placed — the agent writes a structured log entry.

const fs = require('fs');
const path = require('path');

function writeJournalEntry({ marketData, decision, order, timestamp }) {
  const entry = {
    timestamp,
    market_snapshot: marketData,
    agent_decision: decision,
    order_result: order || 'NO_ORDER_PLACED',
  };

  const logPath = path.join('./journal', `${timestamp.split('T')[0]}.jsonl`);
  fs.mkdirSync('./journal', { recursive: true });
  fs.appendFileSync(logPath, JSON.stringify(entry) + '\n');
}

Using .jsonl (JSON Lines) means each cycle appends one line. You can query the file later to analyze patterns — which signals Claude acted on, which it passed, and whether the high-confidence calls outperformed the medium-confidence ones.

This journaling approach is exactly what makes self-improving AI agents with scheduled tasks actually work: the agent’s own history becomes training data for better future decisions.


Step 6: Wire Everything Into a Claude Code Routine

Now you need to turn this into a scheduled routine. Claude Code Routines let you define a task that runs on a schedule using natural language, a shell command, or a script path.

Create your main entry point:

// agent.js
const { getAccount, getLatestQuote } = require('./alpaca');
const { getTradeDecision } = require('./claude');
const { executeDecision } = require('./execution');
const { writeJournalEntry } = require('./journal');
const { buildMarketData } = require('./research');

async function runCycle() {
  const timestamp = new Date().toISOString();
  console.log(`Starting cycle: ${timestamp}`);

  const marketData = await buildMarketData();
  const decision = await getTradeDecision(marketData);
  const order = await executeDecision(decision);
  
  writeJournalEntry({ marketData, decision, order, timestamp });
  
  console.log(`Cycle complete. Decision: ${decision.decision}`);
}

runCycle().catch(console.error);

Then in Claude Code, create a routine that calls this script. In your CLAUDE.md file at the project root, define the routine:

## Routines

### trading-cycle
Schedule: every 15 minutes on weekdays between 9:30 AM and 4:15 PM ET
Command: node agent.js
Description: Run one full trading cycle — research, decision, execution, journal

Claude Code will parse this and register it as a scheduled routine. You can also define this programmatically through the Claude Code SDK if you want more control over the schedule definition.

If you’re unsure whether to use Claude Code’s native scheduling or loop mode, the comparison between Claude Code Loop and Scheduled Tasks breaks down when each makes more sense. For a trading agent, scheduled tasks win — you want precise timing tied to market hours, not a continuous loop.


Step 7: Keep It Running 24/7

A routine defined in Claude Code still needs a process that stays alive. Your local machine isn’t the answer. If it goes to sleep, the agent goes silent.

Your options:

Cloud VM (recommended for this use case): A small VPS running Linux — even a $6/month instance — is enough to host this agent. Run the Claude Code process under systemd or pm2 so it restarts automatically on crash or reboot.

Cloud functions with external scheduler: Deploy agent.js as an AWS Lambda or Google Cloud Function, then trigger it via EventBridge or Cloud Scheduler on your market-hours cron. This keeps costs very low since you’re only paying for execution time.

Docker container on any cloud provider: Containerize the whole thing, push to a registry, and run it on any managed container service. Straightforward to scale if you add more tickers.

For more on the infrastructure side, keeping a Claude Code agent running 24/7 without relying on a local machine covers the deployment options in detail.

One thing to consider: if your agent runs continuously, token costs accumulate. Each 15-minute cycle with a moderately sized context window might cost $0.01–0.05 depending on the model. Over 26 trading cycles a day, that’s $0.26–$1.30 daily. Manageable, but worth tracking. Token budget management for Claude Code agents has practical guidance on keeping API costs from running away.


Step 8: Add Guardrails

An autonomous trading agent with no guardrails is a liability. Add these before you touch live capital:

Position Sizing Limit

Never let the agent risk more than a fixed percentage of the portfolio on any single trade. The system prompt already includes this as an instruction, but enforce it in code too:

function calculateMaxShares(portfolioValue, price, maxRiskPct = 0.02) {
  const maxDollarRisk = portfolioValue * maxRiskPct;
  return Math.floor(maxDollarRisk / price);
}

Pass this calculated maximum to Claude alongside the market data, and validate Claude’s qty output against it before placing the order.

Daily Loss Limit

Track cumulative P&L for the day. If the agent is down more than a set threshold (say, 3% of portfolio value), halt trading for the rest of the session:

function checkDailyLossLimit(account, dailyPnl, limitPct = 0.03) {
  const limit = account.portfolio_value * limitPct;
  if (Math.abs(dailyPnl) > limit && dailyPnl < 0) {
    throw new Error('Daily loss limit reached. Halting trading.');
  }
}

Market Hours Check

Always verify it’s an active trading session before calling the decision or execution steps. Alpaca’s calendar API returns market open/close times and can tell you whether today is a trading day.

These guardrails don’t make the agent infallible, but they cap the downside of a bad signal or an unexpected model hallucination. The AI trading bot challenge with a $10,000 portfolio documented exactly what happens when an agent hits a rough patch without hard stops — worth reading before you go live.


Step 9: Analyze the Journal

The journal is only valuable if you actually read it. Set up a weekly review script that reads the .jsonl files and summarizes:

  • Total trades placed vs. cycles skipped
  • Win rate on completed trades (compare entry price to exit price)
  • Correlation between confidence level and outcome
  • Which tickers and signal conditions led to the best decisions

You can have Claude analyze its own journal. Feed it a week of entries and ask it to identify patterns, systematic mistakes, and areas where the signal quality was weakest. This is how the agent gets better over time — not by training the model, but by improving the strategy encoded in the system prompt.

This feedback loop is the heartbeat pattern applied to trading: the agent checks in on its own performance at a regular interval and uses that data to recalibrate. The heartbeat pattern for AI agent systems explains how to wire this kind of self-review into a broader agentic architecture.


Where Remy Fits

Building this agent involves a lot of moving parts: the research module, the prompt, the execution logic, the journal, the scheduling config, the deployment. If you’re comfortable in Node.js or Python, you can wire these together directly. But if you want a full-stack interface on top — a dashboard showing today’s trades, a view of the journal, controls to pause the agent, maybe a settings page to adjust the watchlist — that’s where spec-driven development starts to make sense.

With Remy, you’d describe that dashboard in a spec: what data it displays, how it connects to the journal files, what controls the user has. Remy compiles that into a full-stack app with a real backend, database, and authentication. You’d end up with a deployable UI for your trading agent without having to build a separate web app from scratch.

The agent logic stays in Claude Code. The interface becomes a Remy app. They’re complementary — and the combination gives you something you can actually use and share, not just a script running in a terminal.


Frequently Asked Questions

Does Alpaca support paper trading for free?

Yes. Alpaca’s paper trading environment is free with any account and uses simulated funds. The API is identical to live trading, so code you write for paper trading works unchanged when you switch to live. Always test in paper mode first.

How often should the agent run?

For most strategies, every 15–30 minutes during market hours is a reasonable starting point. Running more frequently doesn’t necessarily improve results — it increases API costs and token usage, and most edge cases in a swing-trading or trend-following strategy don’t require sub-minute data. Day-trading strategies are a different matter and generally require more sophisticated infrastructure.

What happens if Claude outputs invalid JSON?

Add a try/catch around the JSON parse and a fallback behavior — usually NO_TRADE with a log entry noting the parse failure. You can also use Anthropic’s structured output features or a schema validation library to enforce the response format. Building in error handling upfront saves a lot of debugging later.

Can this agent trade options or crypto?

Alpaca supports crypto trading on its standard API. Options are supported through a separate beta program. The agent architecture described here works for all three, but the signal generation logic and system prompt will need to account for the different characteristics of each instrument — options especially require additional inputs like IV, Greeks, and expiration dates.

Algorithmic trading is legal for retail investors in the US and most other jurisdictions. However, if you manage money for other people (even informally), different rules apply. For personal accounts, you’re fine. Do your own research on your specific situation — the SEC and FINRA publish clear guidance on algorithmic trading for retail participants.

How do I know if the agent is working correctly?

Check three things: (1) the journal files are being written on schedule, (2) the Alpaca paper trading dashboard shows orders matching what the journal says, and (3) the account equity in Alpaca matches what the research module reports at the start of each cycle. If these three sources of truth stay in sync, the agent is operating correctly.


Key Takeaways

  • Claude Code Routines let you schedule a full research-decide-execute-journal cycle without external cron infrastructure or keeping a laptop open
  • The Alpaca API provides a paper trading sandbox with the same interface as live trading — always start there
  • Structure Claude’s output as JSON from the start; it makes execution logic simple and auditable
  • Guardrails in code — not just in prompts — are what prevent a bad signal from becoming a costly mistake
  • The journal is the most underrated part of the build; it’s what turns a trading script into a learning system

If you want to go further, the five Claude Code agentic workflow patterns covers how to evolve this from a simple sequential pipeline to a more autonomous architecture with parallel research workers and multi-agent orchestration.

And if you’d rather build the dashboard and settings interface for this agent than wire up another backend from scratch, give Remy a look — it’s a faster path from “working script” to “actual application.”

Presented by MindStudio

No spam. Unsubscribe anytime.