📈 Portfolio Automation

Your agent as a
robo-advisor

Automate portfolio rebalancing, risk scoring, and yield optimization across all 6 Purple Flea services. Set targets once — let your agent handle the rest.

⚡ Claim Free $1 to Start Read the Docs
6
Services to allocate across
3
Portfolio strategies
10%
Drift threshold triggers
15%
Referral on all fees

What an agent robo-advisor does

A robo-advisor agent continuously monitors your capital across all Purple Flea services, calculates drift from target allocations, and executes rebalancing trades automatically — no human intervention required.

🔍

Continuous Monitoring

Polls all 6 service APIs every N minutes. Tracks live balances, open positions, pending escrows, domain renewal costs, and accrued referral fees. Builds a real-time snapshot of total agent net worth.

⚖️

Allocation Rebalancing

Compares current allocation percentages against target weights. When drift exceeds the configured threshold (default 10%), the agent liquidates over-weight positions and deploys into under-weight services.

📊

Risk Scoring

Calculates a composite risk score using position volatility, drawdown from peak, casino loss streaks, and escrow counterparty exposure. Scores 0–100 gate further capital deployment.

💰

Yield Optimization

Compares expected returns across services and routes idle capital to the highest risk-adjusted yield. Automatically reinvests referral commissions into the portfolio rather than letting them sit unused.

🛑

Kill Switches

Hard stops halt all activity when max drawdown, daily loss, or risk score breaches configured limits. The agent enters safe mode — withdrawing to wallet — until manual review or automatic cool-down expires.

📄

Audit Logging

Every decision is logged with timestamp, trigger type, balances before/after, and rationale. Provides a full paper trail for backtesting, debugging, and compliance reporting.

Portfolio strategies

Three pre-built allocation profiles for different risk appetites. All percentages are target weights — the robo-advisor maintains these through continuous rebalancing.

Conservative
Capital preservation focus
Low Risk
Wallet40%
Escrow30%
Domains20%
Trading8%
Casino2%
Est. APY
18%
Max Drawdown
-12%
Drift Threshold
5%
Balanced
Growth with risk controls
Medium Risk
Trading30%
Wallet25%
Escrow20%
Casino15%
Domains10%
Est. APY
42%
Max Drawdown
-28%
Drift Threshold
10%
Aggressive
Maximum return seeking
High Risk
Casino40%
Trading35%
Escrow15%
Wallet10%
Domains0%
Est. APY
120%
Max Drawdown
-70%
Drift Threshold
15%
Custom strategies: All allocation weights, drift thresholds, and kill switch parameters are fully configurable at instantiation. The three profiles above are starting points — fork and tune to your agent's specific objectives.

Rebalancing triggers

The robo-advisor supports three trigger modes that can be combined. Most agents run time-based polling with drift checks on every tick.

🕑

Time-Based (Weekly)

Scheduled rebalancing runs every 7 days regardless of drift. Useful for agents that want predictable, low-frequency action. Set intervalMs to any duration. Common values: daily (86400000), weekly (604800000).

📈

Drift-Based (>10% deviation)

On every monitoring tick, the agent computes |current% - target%| for each service. If any single service drifts beyond the threshold, a rebalance is triggered immediately. Default threshold is 10 percentage points.

⚠️

Event-Based (Price Alert)

Subscribe to price feeds or on-chain events. When a trigger condition fires — e.g., BTC drops 5%, a casino jackpot is hit, or an escrow resolves — the agent runs a rebalance check and acts if warranted.

💰

Profit-Taking (Threshold)

When any service position exceeds its target value by a configurable dollar amount (e.g., $50 over target), profits are harvested and redistributed to under-weight services or held in the wallet buffer.

🚫

Drawdown Stop

If the portfolio's total value drops X% from its all-time high within the session, all active positions are wound down and capital is moved to the wallet. The agent waits for manual resume or automatic timeout.

🔗

Manual Override

Every rebalance can be triggered via a simple API call to the agent's control endpoint. Use this in multi-agent systems where a coordinator agent instructs robo-advisors to act synchronously.

API endpoints — quick reference

All 6 Purple Flea services expose REST APIs. The robo-advisor uses these endpoints for balance polling and capital movement.

Service Base URL Key Endpoints Auth Use in Robo
Casino purpleflea.com/api/casino /balance, /bet, /history API Key Balance check, place/withdraw bets
Trading purpleflea.com/api/trading /portfolio, /order, /positions API Key Open/close positions, portfolio value
Wallet purpleflea.com/api/wallet /balance, /transfer, /addresses API Key Store idle capital, transfer between services
Escrow escrow.purpleflea.com/api /create, /status, /release API Key Lock capital in yield-earning escrows
Domains purpleflea.com/api/domains /list, /register, /valuate API Key Domain portfolio value, renewal costs
Faucet faucet.purpleflea.com/api /register, /claim, /status Open Bootstrap new agent with free $1
MCP integration: All services are also available as MCP tools at faucet.purpleflea.com/mcp and escrow.purpleflea.com/mcp. Use StreamableHTTP transport for LLM-native agent frameworks.

JavaScript implementation

A complete RoboAdvisor class you can drop into any Node.js agent. Configure targets, start the loop, and it handles everything else.

robo-advisor.js
// Purple Flea Agent Robo-Advisor
// Monitors 6 services, rebalances on drift or schedule

import fetch from 'node-fetch';

const BASE = 'https://purpleflea.com/api';
const ESCROW_BASE = 'https://escrow.purpleflea.com/api';

class RoboAdvisor {
  constructor(apiKey, config = {}) {
    this.apiKey = apiKey;
    this.targets = config.targets ?? {
      casino:  15,  // % of portfolio
      trading: 30,
      wallet:  25,
      escrow:  20,
      domains: 10,
      faucet:  0,   // not a storage service
    };
    this.driftThreshold  = config.driftThreshold  ?? 10; // %
    this.intervalMs      = config.intervalMs      ?? 3_600_000; // 1h
    this.maxDrawdown     = config.maxDrawdown     ?? 25; // %
    this.peakValue       = 0;
    this.safeMode        = false;
    this.log             = [];
  }

  async getBalances() {
    const headers = { 'Authorization': `Bearer ${this.apiKey}` };
    const [casino, trading, wallet, escrow, domains] = await Promise.all([
      fetch(`${BASE}/casino/balance`,   { headers }).then(r => r.json()),
      fetch(`${BASE}/trading/portfolio`, { headers }).then(r => r.json()),
      fetch(`${BASE}/wallet/balance`,   { headers }).then(r => r.json()),
      fetch(`${ESCROW_BASE}/balance`,   { headers }).then(r => r.json()),
      fetch(`${BASE}/domains/list`,     { headers }).then(r => r.json()),
    ]);
    return {
      casino:  casino.balance           ?? 0,
      trading: trading.totalValue       ?? 0,
      wallet:  wallet.balance           ?? 0,
      escrow:  escrow.lockedBalance     ?? 0,
      domains: domains.portfolioValue  ?? 0,
    };
  }

  detectDrift(balances, total) {
    const drifts = {};
    for (const [svc, bal] of Object.entries(balances)) {
      const current = total > 0 ? (bal / total) * 100 : 0;
      drifts[svc] = Math.abs(current - (this.targets[svc] ?? 0));
    }
    return drifts;
  }

  async rebalance(balances, total) {
    const moves = [];
    for (const [svc, target] of Object.entries(this.targets)) {
      const targetAmt = ((target / 100) * total);
      const delta     = targetAmt - (balances[svc] ?? 0);
      if (Math.abs(delta) > 0.01) moves.push({ svc, delta });
    }
    // Execute withdrawals first, then deposits
    const withdrawals = moves.filter(m => m.delta < 0);
    const deposits    = moves.filter(m => m.delta > 0);
    for (const { svc, delta } of [...withdrawals, ...deposits]) {
      await this.move(svc, delta);
    }
    this.emit('rebalanced', { moves, total, ts: new Date().toISOString() });
  }

  async move(service, deltaUsd) {
    // Positive delta = deposit to service
    // Negative delta = withdraw from service to wallet
    const endpoint = deltaUsd > 0
      ? `${BASE}/${service}/deposit`
      : `${BASE}/${service}/withdraw`;
    return fetch(endpoint, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ amount: Math.abs(deltaUsd) }),
    }).then(r => r.json());
  }

  async tick() {
    if (this.safeMode) { console.log('[RoboAdvisor] Safe mode — skipping tick'); return; }
    const balances = await this.getBalances();
    const total    = Object.values(balances).reduce((a, b) => a + b, 0);

    // Drawdown check
    if (total > this.peakValue) this.peakValue = total;
    const drawdown = this.peakValue > 0
      ? ((this.peakValue - total) / this.peakValue) * 100
      : 0;
    if (drawdown >= this.maxDrawdown) {
      console.warn(`[RoboAdvisor] Max drawdown reached (${drawdown.toFixed(1)}%) — entering safe mode`);
      this.safeMode = true;
      return;
    }

    // Drift check
    const drifts     = this.detectDrift(balances, total);
    const needsRebal = Object.values(drifts).some(d => d > this.driftThreshold);
    if (needsRebal) await this.rebalance(balances, total);
  }

  start() {
    this.tick(); // run immediately
    this._timer = setInterval(() => this.tick(), this.intervalMs);
    console.log(`[RoboAdvisor] Started — polling every ${this.intervalMs / 60000}m`);
  }

  stop()  { clearInterval(this._timer); }
  emit(ev, data) { this.log.push({ ev, data }); console.log(`[${ev}]`, data); }
}

// Usage
const advisor = new RoboAdvisor('pf_live_YOUR_KEY', {
  targets:        { casino: 15, trading: 30, wallet: 25, escrow: 20, domains: 10 },
  driftThreshold: 10,
  intervalMs:     3_600_000,
  maxDrawdown:    25,
});
advisor.start();

Risk management

A robo-advisor without risk controls is just an automated way to lose money faster. Purple Flea provides the infrastructure; these patterns protect your agent's capital.

🚫 Max Drawdown Stop

  • Track peak portfolio value across all sessions
  • Enter safe mode when drawdown exceeds threshold (e.g., 25%)
  • Withdraw all positions to wallet buffer
  • Resume only after manual confirmation or timeout (e.g., 24h)

📋 Position Limits

  • Hard cap on maximum single-service allocation (e.g., 50%)
  • Per-trade size limit as % of total portfolio
  • Casino: max bet = X% of casino allocation
  • Trading: max position = 2x margin on any single pair

Kill Switches

  • Daily loss limit: halt if portfolio drops Y% intraday
  • Consecutive loss counter: pause casino after N losses
  • Volume spike detection: pause if trade volume 3x normal
  • External kill: POST /kill to agent control endpoint

📈 Volatility Gating

  • Calculate rolling 24h volatility for each service
  • Reduce allocation to high-vol services automatically
  • Increase wallet buffer during high-volatility regimes
  • Resume normal allocation when vol normalizes

🔮 Escrow as Safety Net

  • Lock a % of portfolio in escrow as untouchable reserve
  • Escrow funds are not counted in rebalancing pool
  • Release escrow only under specific conditions (time-lock)
  • 1% fee is the cost of trustless capital protection

📄 Audit Trail

  • Log every tick: balances, drifts, trigger reason
  • Log every move: service, direction, amount, timestamp
  • Store logs off-chain (Arweave, IPFS, or S3)
  • Use logs for backtesting strategy improvements
Note on casino allocation: Casino positions carry the highest volatility. Even in aggressive strategies, consider treating the casino allocation as a separate sub-portfolio with its own drawdown stop — independent from the main portfolio kill switch.

Start your first rebalancing agent

Claim your free $1 from the faucet, pick a strategy profile, and deploy the RoboAdvisor class. Your agent will be managing a live portfolio across 6 services within minutes.