Skip to content
Research · AI/ML

Building Autonomous Trading Agents with Real-World Intelligence

From news ingestion to trade execution in under 30 seconds — the architecture of Vex Capital

14 min readVenym Labs Research
Study record/AI/ML
Published

Summary

From news ingestion to trade execution in under 30 seconds — the architecture of Vex Capital

Published
Filed under
AI/ML
Reading time
14 min read
Sections
10
Research by
Venym Labs Research
Research is not peer reviewedvenym.io/research/building-autonomous-trading-agents-with-…

Autonomous Trading Agents

Building Autonomous Trading Agents with Real-World Intelligence#

From news ingestion to trade execution in under 30 seconds — the architecture of Vex Capital#


The promise of AI trading agents is intoxicating: a system that reads the news, understands markets, manages risk, and executes trades — all without human intervention. The reality, for most teams, is a collection of brittle scripts that break the moment market conditions change.

At Venym Labs, we built Vex Capital — an autonomous trading agent that has been running continuously, processing thousands of news events and executing trades on Hyperliquid perpetual futures. This document is an unfiltered look at the architecture, the trade-offs, and the lessons learned.

The 30-Second Pipeline#

The north star metric for Vex Capital is simple: from news event to executed trade in under 30 seconds. This is not a theoretical target — it's a measured operational benchmark.

text
T+0s     News event occurs (breaking headline published)
T+3s     Ingest pipeline captures article
T+6s     Embedding generated from article text
T+8s     Vector similarity search returns historical analogs
T+10s    Signal generated (direction, magnitude, confidence)
T+12s    Risk manager evaluates and approves trade
T+14s    Execution engine submits order to Hyperliquid
T+16s    Order confirmed on-chain
T+30s    Position monitored, stop-loss and take-profit set

This pipeline runs continuously, 24/7, processing events across 12 news categories.

System Architecture#

Layer 1: News Ingestion — The Ingest Pipeline#

The foundation of any news-driven trading system is reliable, fast data ingestion. Vex Capital's Ingest pipeline is a dedicated service that:

Data Sources (12 Categories)#

text
┌──────────────────────────────────────────┐
│           NEWS CATEGORIES                 │
├──────────────────────────────────────────┤
│ 1.  Crypto & Blockchain                  │
│ 2.  Macroeconomics (Fed, CPI, jobs)      │
│ 3.  Regulation & Policy                   │
│ 4.  DeFi & Lending                        │
│ 5.  NFTs & Digital Assets                 │
│ 6.  Gaming & Metaverse                    │
│ 7.  AI & Technology                       │
│ 8.  Geopolitics                           │
│ 9.  Energy & Commodities                  │
│ 10. Traditional Finance (TradFi)          │
│ 11. Corporate Events (earnings, M&A)      │
│ 12. Social Media Sentiment (Twitter/X)    │
└──────────────────────────────────────────┘

Ingestion Pipeline Code#

typescript
class IngestPipeline {
  private sources: NewsSource[];
  private dedupCache: Map<string, number>;
  
  async poll(): Promise<Article[]> {
    const results = await Promise.allSettled(
      this.sources.map(s => s.fetch())
    );
    
    const articles = results
      .filter((r): r is FulfilledResult<Article[]> => r.status === 'fulfilled')
      .flatMap(r => r.value)
      .filter(a => !this.isDuplicate(a))
      .map(a => this.normalize(a));
    
    return articles;
  }
  
  private isDuplicate(article: Article): boolean {
    // Fingerprint: first 8 words of headline + source
    const fingerprint = this.fingerprint(article);
    if (this.dedupCache.has(fingerprint)) return true;
    this.dedupCache.set(fingerprint, Date.now());
    
    // Evict old entries (24h TTL)
    for (const [key, ts] of this.dedupCache) {
      if (Date.now() - ts > 24 * 60 * 60 * 1000) {
        this.dedupCache.delete(key);
      }
    }
    return false;
  }
}

Layer 2: Vector Embeddings for Market Event Correlation#

This is where Vex Capital diverges from conventional trading systems. Instead of extracting features manually (sentiment scores, keyword counts, etc.), we embed the entire article into a high-dimensional vector and use similarity search to find historical analogs.

The Embedding Process#

typescript
import { embed } from './embedding-model';

async function processArticle(article: Article): Promise<Signal> {
  // 1. Create rich text representation
  const richText = [
    article.headline,
    article.summary,
    `Category: ${article.category}`,
    `Source: ${article.source}`,
    `Entities: ${article.entities.join(', ')}`,
  ].join('\n');
  
  // 2. Generate embedding
  const embedding = await embed(richText);
  // → 768-dimensional float vector
  
  // 3. Find historical analogs
  const analogs = await vectorStore.search(embedding, {
    k: 25,
    filters: {
      category: article.category,
      minSimilarity: 0.7,
    },
    includeMetadata: ['market_outcome', 'time_delta'],
  });
  
  // 4. Compute expected market impact
  const expectedImpact = analogs.reduce((acc, a, i) => {
    const weight = a.similarity * Math.exp(-a.age_days / 120);
    return acc + a.market_outcome.price_change_1h * weight;
  }, 0) / analogs.reduce((acc, a) => {
    const weight = a.similarity * Math.exp(-a.age_days / 120);
    return acc + weight;
  }, 0);
  
  // 5. Generate signal
  const confidence = Math.min(0.95, analogs.reduce((acc, a) => 
    acc + a.similarity, 0) / analogs.length * 1.5);
  
  return {
    direction: expectedImpact > 0 ? 'LONG' : 'SHORT',
    magnitude: Math.abs(expectedImpact),
    confidence,
    asset: inferTargetAsset(article),
    historicalAnalogs: analogs.slice(0, 5),
    sourceArticle: article,
  };
}

Why This Works#

The fundamental insight is that similar news events produce similar market outcomes. Not because of simple word matching, but because:

  1. Market participants react to meaning, not words. "SEC rejects Bitcoin ETF" and "US regulator denies crypto fund approval" produce the same market reaction despite no shared keywords.

  2. Historical analogs are abundant. In crypto, we've seen thousands of hack announcements, regulation news, ETF decisions, and macro events. For any new event, there are 10-50 genuinely similar historical events.

  3. Context matters. The same headline can mean different things in different market regimes. Vector similarity search naturally captures this because recent similar events get higher weight.

  4. Cross-category signals emerge. Sometimes a macro headline (CPI data) creates a DeFi-specific opportunity. The embedding space captures these cross-category correlations automatically.

Layer 3: Risk Management as Code#

Risk management in Vex Capital is not a spreadsheet or a dashboard — it's a code layer that sits between signal generation and trade execution. Every trade must pass through the risk manager, and the risk manager can unilaterally reject any trade.

Risk Framework#

typescript
class RiskManager {
  private state: RiskState;
  
  async evaluate(signal: Signal): Promise<RiskDecision> {
    const checks = {
      positionSize: this.checkPositionSize(signal),
      portfolioRisk: this.checkPortfolioRisk(signal),
      drawdownLimit: this.checkDrawdownLimit(),
      correlationLimit: this.checkCorrelation(signal),
      liquidityCheck: this.checkLiquidity(signal),
      volatilityRegime: this.checkVolatilityRegime(),
      newsFreshness: this.checkNewsFreshness(signal),
      executionFeasibility: this.checkExecutionFeasibility(signal),
    };
    
    const failed = Object.entries(checks)
      .filter(([_, passed]) => !passed);
    
    if (failed.length > 0) {
      return {
        approved: false,
        reasons: failed.map(([check]) => check),
      };
    }
    
    return {
      approved: true,
      adjustedSize: this.computePositionSize(signal),
      stopLoss: this.computeStopLoss(signal),
      takeProfit: this.computeTakeProfit(signal),
      maxHoldingTime: this.computeMaxHoldingTime(signal),
    };
  }
  
  private computePositionSize(signal: Signal): number {
    const baseSize = this.config.maxPositionSize;
    const confidenceScale = signal.confidence;  // 0-1
    const drawdownScale = 1 - (this.state.currentDrawdown / this.config.maxDailyDrawdown);
    const volatilityScale = this.getVolatilityScale(signal.asset);
    
    return baseSize * confidenceScale * drawdownScale * volatilityScale;
  }
}

Key Risk Parameters#

ParameterValueRationale
Max position size10% of portfolioLimits single-trade impact
Max daily drawdown3%Hard stop for the day
Max correlation exposure3 correlated positionsDiversification requirement
Volatility scaling0.5x in high-vol regimesReduce size when uncertainty is high
Consecutive loss limit5 losses → 24h cooldownPrevents tilt-driven losses
News freshnessReject signals from >15min old articlesStale signals have no edge

The Circuit Breaker#

The most important risk feature is the circuit breaker:

typescript
class CircuitBreaker {
  private consecutiveLosses = 0;
  private dailyPnL = 0;
  private lastTradeTime = 0;
  
  async check(): Promise<boolean> {
    // Hard stop: daily drawdown exceeded
    if (this.dailyPnL < -this.config.maxDailyDrawdown) {
      this.halt('DAILY_DRAWDOWN_EXCEEDED');
      return false;
    }
    
    // Soft stop: consecutive losses
    if (this.consecutiveLosses >= 5) {
      this.cooldown(24 * 60 * 60 * 1000); // 24 hours
      return false;
    }
    
    // Rate limit: no more than 1 trade per 5 minutes
    if (Date.now() - this.lastTradeTime < 5 * 60 * 1000) {
      return false;
    }
    
    return true;
  }
}

Layer 4: Execution Engine#

The execution engine is responsible for translating approved trades into actual orders on Hyperliquid. It handles:

Order Management#

typescript
class ExecutionEngine {
  async execute(decision: RiskDecision, signal: Signal): Promise<TradeResult> {
    const order = this.buildOrder(decision, signal);
    
    // 1. Check current market depth
    const depth = await this.getMarketDepth(signal.asset);
    const maxSlippage = this.computeMaxSlippage(order, depth);
    
    if (maxSlippage > this.config.maxSlippage) {
      return { status: 'REJECTED', reason: 'EXCESSIVE_SLIPPAGE' };
    }
    
    // 2. Submit limit order (not market order)
    const limitPrice = this.computeLimitPrice(signal.direction, depth);
    const orderResult = await this.submitOrder({
      asset: signal.asset,
      side: signal.direction === 'LONG' ? 'BUY' : 'SELL',
      size: decision.adjustedSize,
      price: limitPrice,
      type: 'LIMIT',
      tif: 'IOC',  // Immediate or Cancel
    });
    
    if (!orderResult.filled) {
      // Retry with market order if slippage is still acceptable
      return this.fallbackToMarket(order, depth);
    }
    
    // 3. Set stop-loss and take-profit
    await this.setRiskOrders(orderResult, {
      stopLoss: decision.stopLoss,
      takeProfit: decision.takeProfit,
    });
    
    // 4. Record trade for portfolio tracking
    this.recordTrade(orderResult, signal, decision);
    
    return { status: 'FILLED', order: orderResult };
  }
}

Execution Principles#

  1. Limit orders first, market orders as fallback. Always try to get price improvement. Only fall back to market orders when the signal urgency justifies the slippage cost.

  2. Slippage budgets. Every trade has a maximum acceptable slippage based on signal confidence and market conditions. If the market can't absorb the order within budget, the trade is rejected.

  3. IOC (Immediate or Cancel) for limit orders. We don't want orders sitting in the book. If the limit price isn't immediately available, we either fall back to market or skip the trade.

  4. Stop-losses are non-negotiable. Every trade has a stop-loss set at order submission time. No exceptions.

The Future: Multi-Agent Coordination#

Vex Capital today is a single agent. The next evolution is multi-agent coordination:

text
┌─────────────────────────────────────────────┐
│            AGENT COORDINATOR                 │
│                                             │
│  ┌───────────┐  ┌───────────┐  ┌──────────┐ │
│  │  Macro    │  │  Crypto   │  │  DeFi    │ │
│  │  Agent    │  │  Agent    │  │  Agent   │ │
│  └─────┬─────┘  └─────┬─────┘  └────┬─────┘ │
│        │              │             │        │
│  ┌─────┴──────────────┴─────────────┴─────┐  │
│  │         PORTFOLIO COORDINATOR          │  │
│  │  (Cross-agent risk management)          │  │
│  └────────────────────────────────────────┘  │
└─────────────────────────────────────────────┘

Each specialized agent monitors its domain and generates signals. The portfolio coordinator ensures the combined portfolio respects overall risk constraints. This enables:

  • Domain expertise. Each agent can be fine-tuned for its specific market
  • Portfolio-level optimization. Risk management considers all positions, not just individual trades
  • Parallel processing. Agents run independently, scaling linearly

The Agent Loop#

Lessons Learned#

What Worked#

  1. Embedding-based similarity search is the single biggest alpha source. It captures nuance that no rule-based system can match, and the signal degrades gracefully as you go further back in time.

  2. The risk manager as a veto layer is essential. Without it, the agent would overtrade during high-volatility periods and blow up during tail events.

  3. Limit orders > market orders. The slippage savings from limit orders compound significantly over thousands of trades.

  4. Keeping the pipeline simple. Every additional processing step adds latency. The 30-second target forces architectural discipline.

What Didn't Work#

  1. Real-time sentiment APIs. External sentiment APIs (LunarCrush, Santiment) are too slow (5-15 second latency) and too coarse (single sentiment score, no nuance). We replaced them entirely with our embedding system.

  2. Technical analysis as a signal. We initially tried incorporating RSI, MACD, and moving averages. They added noise without improving returns. For news-driven strategies, price action from the last 24 hours is already reflected in the market.

  3. High-frequency trading. We explored sub-second strategies but found the infrastructure costs (co-located servers, premium data feeds) exceeded the alpha generated. News-driven strategies with 10-30 second horizons are more capital-efficient.


Key Takeaways#

  1. The 30-second pipeline is achievable with careful architecture. News ingestion (3s), embedding (3s), similarity search (2s), signal generation (2s), risk check (2s), execution (4s). Each step is independently fast; the challenge is connecting them without introducing blocking calls or excessive serialization.

  2. Vector embeddings are the secret sauce. By encoding news articles into a shared vector space and comparing against historical market outcomes, you get a signal that captures semantic meaning, historical analogy, and confidence — all from a single similarity search.

  3. Risk management must be a code layer with veto power. The risk manager is not an advisor — it's a gatekeeper. Every trade must pass through it, and it can unilaterally reject any signal regardless of strength.

  4. Limit orders and slippage budgets preserve edge. Over thousands of trades, the compounding effect of better execution (limit vs. market) and disciplined slippage management is material.

  5. Multi-agent coordination is the next frontier. Specialized agents for different market domains, coordinated by a portfolio-level risk manager, will unlock the next order of magnitude in autonomous trading capability.


Venym Labs Research — Published 2025-03-14

Venym Labs ResearchReturn to the archive

From research to a working system

A better question. A tested answer.

Bring the system, the constraint or the question. We will work out what the evidence needs to show.

New message
ToVconnect@venym.io
SubjectResearch-backed system inquiry
Opens in your mail appSend the question