# Greenhelix Copy Trading Infrastructure

> Copy Trading Infrastructure: Protocol-Agnostic Copy Trading with Verified Leader Performance. Build copy trading infrastructure with verified leader performance, follower allocation models, slippage handling, performance escrow, and revenue sharing. Includes detailed Python code examples with marketplace and escrow integration patterns.

- Skill: `lord1egypt/greenhelix-copy-trading-infrastructure` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lord1egypt/greenhelix-copy-trading-infrastructure`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lord1egypt/greenhelix-copy-trading-infrastructure/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Finance & Business
- License: MIT
- Author: Lord1Egypt (https://skillmd.com/u/lord1egypt)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/lord1egypt/greenhelix-copy-trading-infrastructure

---

# Copy Trading Infrastructure: Protocol-Agnostic Copy Trading with Verified Leader Performance

> **Notice**: This is an educational guide with illustrative code examples.
> It does not execute code or install dependencies.
> All examples use the GreenHelix sandbox (https://sandbox.greenhelix.net) which
> provides 500 free credits — no API key required to get started.
>
> **Referenced credentials** (you supply these in your own environment):
> - `GREENHELIX_API_KEY`: API authentication for GreenHelix gateway (read/write access to purchased API tools only)
> - `AGENT_SIGNING_KEY`: Cryptographic signing key for agent identity (Ed25519 key pair for request signing)


Copy trading is the fastest-growing segment of automated trading, projected to reach $4.2 billion by 2027 according to Allied Market Research. But the current generation of platforms -- eToro, Bybit Copy, NAGA, ZuluTrade -- share a fundamental trust problem that limits their growth and exposes followers to unnecessary risk. Leader performance is self-reported or platform-curated with opaque methodology. Followers have no recourse when leaders lose money beyond closing the copy relationship after the damage is done. Platforms take 20-30% of performance fees while adding no verification, no escrow protection, and no cryptographic proof that stated returns actually occurred. The result is an ecosystem where the most profitable strategy for a leader is not to trade well, but to attract followers, collect fees, and let survivorship bias do the marketing. This guide builds something different: protocol-agnostic copy trading infrastructure where leader performance is cryptographically verified through Ed25519-signed trade records, follower allocations are risk-managed through configurable models, and revenue sharing flows through escrow that releases only when performance criteria are met. The trust layer is GreenHelix. Leaders register as service providers on the marketplace. Followers discover and evaluate them using verified metrics. Performance escrow protects follower capital. Revenue splits are enforced by smart contracts, not gentleman's agreements. The entire system is exchange-agnostic -- the same infrastructure works whether your leaders trade on Binance, Coinbase, Interactive Brokers, or a DEX.
1. [Copy Trading Architecture](#chapter-1-copy-trading-architecture)
2. [CopyTradingLeader Class](#chapter-2-copytradingleader-class)

## What You'll Learn
- Chapter 1: Copy Trading Architecture
- Chapter 2: CopyTradingLeader Class
- Chapter 3: CopyTradingFollower Class
- Chapter 4: Allocation Models
- Chapter 5: Slippage Handling
- Chapter 6: Performance Escrow
- Chapter 7: Revenue Sharing
- Next Steps
- What's Next

## Full Guide

# Copy Trading Infrastructure: Protocol-Agnostic Copy Trading with Verified Leader Performance

Copy trading is the fastest-growing segment of automated trading, projected to reach $4.2 billion by 2027 according to Allied Market Research. But the current generation of platforms -- eToro, Bybit Copy, NAGA, ZuluTrade -- share a fundamental trust problem that limits their growth and exposes followers to unnecessary risk. Leader performance is self-reported or platform-curated with opaque methodology. Followers have no recourse when leaders lose money beyond closing the copy relationship after the damage is done. Platforms take 20-30% of performance fees while adding no verification, no escrow protection, and no cryptographic proof that stated returns actually occurred. The result is an ecosystem where the most profitable strategy for a leader is not to trade well, but to attract followers, collect fees, and let survivorship bias do the marketing. This guide builds something different: protocol-agnostic copy trading infrastructure where leader performance is cryptographically verified through Ed25519-signed trade records, follower allocations are risk-managed through configurable models, and revenue sharing flows through escrow that releases only when performance criteria are met. The trust layer is GreenHelix. Leaders register as service providers on the marketplace. Followers discover and evaluate them using verified metrics. Performance escrow protects follower capital. Revenue splits are enforced by smart contracts, not gentleman's agreements. The entire system is exchange-agnostic -- the same infrastructure works whether your leaders trade on Binance, Coinbase, Interactive Brokers, or a DEX.

---

## Table of Contents

1. [Copy Trading Architecture](#chapter-1-copy-trading-architecture)
2. [CopyTradingLeader Class](#chapter-2-copytradingleader-class)
3. [CopyTradingFollower Class](#chapter-3-copytradingfollower-class)
4. [Allocation Models](#chapter-4-allocation-models)
5. [Slippage Handling](#chapter-5-slippage-handling)
6. [Performance Escrow](#chapter-6-performance-escrow)
7. [Revenue Sharing](#chapter-7-revenue-sharing)
9. [What's Next](#whats-next)

---

## Chapter 1: Copy Trading Architecture

### The Leader-Follower Model with GreenHelix as Trust Layer

Copy trading is conceptually simple: a leader executes trades, and followers mirror those trades in their own accounts. The complexity lies entirely in trust. How does a follower know the leader's track record is real? How does the follower limit their exposure if the leader blows up? How does the leader get paid fairly for generating alpha? And how do both parties resolve disputes without a centralized authority that has perverse incentives?

Traditional platforms solve these problems by becoming the centralized authority. eToro holds both leader and follower funds, controls the performance data, sets the fee structure, and resolves disputes at its discretion. This works until it does not -- platforms can selectively promote leaders who generate revenue, suppress negative performance data, or structure fees that incentivize volume over performance.

The GreenHelix architecture replaces platform trust with cryptographic verification. Leaders submit signed performance metrics that cannot be fabricated. Followers subscribe through performance escrow that protects their capital. Revenue sharing flows through escrow contracts that release only when agreed-upon criteria are met. The platform does not hold funds, does not curate leaders, and does not resolve disputes -- the protocol does.

### Architecture Overview

```
+-------------------+       +---------------------+       +-------------------+
|   Copy Leader     |       |   GreenHelix API    |       |   Copy Follower   |
|                   |       |                     |       |                   |
|  Execute trades   |       |                     |       |                   |
|  on exchange      |       |                     |       |                   |
|       |           |       |                     |       |                   |
|  Sign trade       |       |                     |       |                   |
|  record (Ed25519) |       |                     |       |                   |
|       |           |       |                     |       |                   |
|  submit_metrics  -------> |  Verified Metrics   |       |                   |
|  publish_event   -------> |  Event Bus          | ----> |  Receive signal   |
|  register_service ------> |  Marketplace        | ----> |  search_services  |
|                   |       |                     |       |  subscribe        |
|                   |       |  Performance Escrow | <---- |  create_escrow    |
|                   |       |       |              |       |       |           |
|  claim_revenue  <-------- |  release_escrow     |       |  execute trade    |
|                   |       |  (criteria met)     |       |  on own exchange  |
|                   |       |                     |       |       |           |
|  get_reputation  <------> |  Reputation Engine  | <---> |  get_reputation   |
+-------------------+       +---------------------+       +-------------------+
```

The data flow works as follows. A leader executes a trade on their exchange of choice -- Binance, Coinbase, Interactive Brokers, a DEX, it does not matter. The leader's bot signs the trade record with its Ed25519 private key and publishes it to the GreenHelix event bus via `publish_event`. Simultaneously, the leader submits aggregate performance metrics via `submit_metrics` -- win rate, Sharpe ratio, max drawdown, total return -- that become part of their verifiable reputation. Followers discover leaders through `search_services` on the marketplace, evaluate them using `get_agent_reputation` and `get_claim_chains`, subscribe by creating a performance escrow via `create_escrow`, and receive trade signals through webhooks registered with `register_webhook`. When a signal arrives, the follower's bot applies its allocation model, adjusts for risk limits, and executes the corresponding trade on the follower's own exchange account. At the end of each evaluation period, the escrow contract checks whether the leader met the agreed performance criteria. If yes, the leader's revenue share is released. If not, the follower's escrow deposit is returned.

### GreenHelix Tools Used

This guide uses the following GreenHelix API tools:

| Tool | Purpose |
|---|---|
| `register_agent` | Register leader and follower identities with Ed25519 public keys |
| `register_service` | List a leader's copy trading service on the marketplace |
| `search_services` | Discover available copy trading leaders |
| `create_escrow` | Create performance escrow protecting follower deposits |
| `release_escrow` | Release escrow when performance criteria are met |
| `submit_metrics` | Submit verified performance metrics for leaders |
| `get_agent_reputation` | Retrieve a leader's verified reputation score |
| `get_claim_chains` | Verify the integrity of a leader's performance history |
| `publish_event` | Broadcast trade signals to followers via the event bus |
| `register_webhook` | Register follower endpoints to receive trade signals |
| `create_sla` | Define performance SLA between leader and follower |
| `check_sla_compliance` | Verify leader meets agreed SLA terms |

### Why Protocol-Agnostic Matters

Locking copy trading to a single exchange limits the leader pool and the follower pool. A leader who trades BTC/USDT on Binance Futures should be copyable by a follower on Bybit, OKX, or a self-custodied DEX. The GreenHelix event bus decouples signal generation from signal execution. The leader publishes a normalized trade signal -- symbol, side, size as a percentage of portfolio, entry price, stop loss, take profit -- and each follower's execution engine translates that signal into exchange-specific orders. This is the same architecture used by institutional signal distribution networks like Portware and FlexTrade, scaled down to retail.

---

## Chapter 2: CopyTradingLeader Class

### Leader Registration and Service Listing

A copy trading leader is an agent that executes trades on one or more exchanges and broadcasts those trades as signals. Before a leader can attract followers, they must register their identity, list their service on the marketplace, and begin building a verified track record.

#### Step 1: Generate an Ed25519 Keypair

```python
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives import serialization
import base64

private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()

private_bytes = private_key.private_bytes(
    encoding=serialization.Encoding.Raw,
    format=serialization.PrivateFormat.Raw,
    encryption_algorithm=serialization.NoEncryption()
)
public_bytes = public_key.public_bytes(
    encoding=serialization.Encoding.Raw,
    format=serialization.PublicFormat.Raw
)

PRIVATE_KEY_B64 = base64.b64encode(private_bytes).decode()
PUBLIC_KEY_B64 = base64.b64encode(public_bytes).decode()
```

Store the private key in a secrets manager. It signs every trade record and performance metric submission -- if it leaks, an attacker can fabricate your track record.

#### Step 2: Register and List

```bash
# Register the leader agent
curl -X POST https://sandbox.greenhelix.net/v1 \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "register_agent",
    "input": {
      "agent_id": "leader-crypto-momentum-01",
      "public_key": "'"$PUBLIC_KEY_B64"'",
      "name": "Crypto Momentum Alpha"
    }
  }'

# List the copy trading service on the marketplace
curl -X POST https://sandbox.greenhelix.net/v1 \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "register_service",
    "input": {
      "agent_id": "leader-crypto-momentum-01",
      "service_type": "copy_trading",
      "name": "Crypto Momentum Alpha -- Copy Trading",
      "description": "Momentum-based crypto trading strategy. BTC/ETH/SOL on Binance Futures. 15-minute to 4-hour timeframes. Target Sharpe > 2.0, max drawdown < 15%.",
      "pricing": {
        "model": "hybrid",
        "subscription_monthly_usd": "49.00",
        "performance_fee_pct": "15.0"
      },
      "metadata": {
        "strategy_type": "momentum",
        "asset_classes": ["crypto"],
        "exchanges": ["binance_futures"],
        "symbols": ["BTCUSDT", "ETHUSDT", "SOLUSDT"],
        "timeframes": ["15m", "1h", "4h"],
        "track_record_months": 18,
        "verified_sharpe": "2.34",
        "verified_max_drawdown_pct": "11.7",
        "verified_win_rate_pct": "58.3",
        "avg_trades_per_week": 12,
        "max_followers": 500
      }
    }
  }'
```

The `max_followers` field is critical. Every additional follower increases market impact when the leader's signals are executed simultaneously. A leader trading $100K with 500 followers at $10K each creates $5.1M of correlated order flow. On illiquid pairs, this causes meaningful slippage -- covered in Chapter 5.

### The CopyTradingLeader Class

```python
import json
import time
import hashlib
import base64
import uuid
from datetime import datetime, timezone
from typing import Optional

import requests
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
    Ed25519PrivateKey,
)
from cryptography.hazmat.primitives import serialization


class CopyTradingLeader:
    """Copy trading leader that broadcasts verified trade signals."""

    def __init__(
        self,
        api_key: str,
        agent_id: str,
        private_key_b64: str,
    ):
        self.api_base = "https://api.greenhelix.net/v1"
        self.api_key = api_key
        self.agent_id = agent_id
        self._private_key = Ed25519PrivateKey.from_private_bytes(
            base64.b64decode(private_key_b64)
        )
        self._trades: list[dict] = []
        self._session = requests.Session()
        self._session.headers.update({
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        })

    def _execute(self, tool: str, input_data: dict) -> dict:
        resp = self._session.post(
            f"{self.api_base}/v1",
            json={"tool": tool, "input": input_data},
        )
        resp.raise_for_status()
        return resp.json()

    def _sign(self, payload: dict) -> str:
        canonical = json.dumps(payload, sort_keys=True, separators=(",", ":"))
        signature = self._private_key.sign(canonical.encode())
        return base64.b64encode(signature).decode()

    def _now_iso(self) -> str:
        return datetime.now(timezone.utc).isoformat()

    def broadcast_trade_signal(
        self,
        symbol: str,
        side: str,
        size_pct: float,
        entry_price: float,
        stop_loss: Optional[float] = None,
        take_profit: Optional[float] = None,
        order_type: str = "market",
        timeframe: str = "1h",
    ) -> dict:
        """Broadcast a trade signal to all followers via the event bus."""
        signal_id = str(uuid.uuid4())
        timestamp = self._now_iso()

        payload = {
            "signal_id": signal_id,
            "leader_id": self.agent_id,
            "symbol": symbol,
            "side": side,
            "size_pct": str(size_pct),
            "entry_price": str(entry_price),
            "order_type": order_type,
            "timeframe": timeframe,
            "timestamp": timestamp,
        }
        if stop_loss is not None:
            payload["stop_loss"] = str(stop_loss)
        if take_profit is not None:
            payload["take_profit"] = str(take_profit)

        payload["signature"] = self._sign(payload)

        result = self._execute("publish_event", {
            "event_type": "copy_trade.signal",
            "payload": payload,
        })

        self._trades.append({
            "signal_id": signal_id,
            "symbol": symbol,
            "side": side,
            "size_pct": size_pct,
            "entry_price": entry_price,
            "stop_loss": stop_loss,
            "take_profit": take_profit,
            "timestamp": timestamp,
            "status": "open",
        })

        return result

    def close_position(
        self,
        signal_id: str,
        exit_price: float,
        pnl_pct: float,
    ) -> dict:
        """Broadcast a position close signal."""
        timestamp = self._now_iso()

        payload = {
            "signal_id": signal_id,
            "leader_id": self.agent_id,
            "action": "close",
            "exit_price": str(exit_price),
            "pnl_pct": str(pnl_pct),
            "timestamp": timestamp,
        }
        payload["signature"] = self._sign(payload)

        result = self._execute("publish_event", {
            "event_type": "copy_trade.close",
            "payload": payload,
        })

        for trade in self._trades:
            if trade["signal_id"] == signal_id:
                trade["status"] = "closed"
                trade["exit_price"] = exit_price
                trade["pnl_pct"] = pnl_pct
                break

        return result

    def submit_performance_metrics(self) -> dict:
        """Submit verified performance metrics to build reputation."""
        closed_trades = [t for t in self._trades if t["status"] == "closed"]
        if not closed_trades:
            return {"status": "no_closed_trades"}

        wins = [t for t in closed_trades if t["pnl_pct"] > 0]
        losses = [t for t in closed_trades if t["pnl_pct"] <= 0]
        pnls = [t["pnl_pct"] for t in closed_trades]

        total_return = sum(pnls)
        win_rate = len(wins) / len(closed_trades) * 100
        avg_win = sum(t["pnl_pct"] for t in wins) / len(wins) if wins else 0
        avg_loss = sum(t["pnl_pct"] for t in losses) / len(losses) if losses else 0
        max_drawdown = self._calculate_max_drawdown(pnls)
        sharpe = self._calculate_sharpe(pnls)

        metrics = {
            "total_trades": len(closed_trades),
            "win_rate_pct": str(round(win_rate, 2)),
            "total_return_pct": str(round(total_return, 4)),
            "avg_win_pct": str(round(avg_win, 4)),
            "avg_loss_pct": str(round(avg_loss, 4)),
            "max_drawdown_pct": str(round(max_drawdown, 4)),
            "sharpe_ratio": str(round(sharpe, 4)),
            "last_updated": self._now_iso(),
        }
        metrics["signature"] = self._sign(metrics)

        return self._execute("submit_metrics", {
            "agent_id": self.agent_id,
            "metrics": metrics,
        })

    def _calculate_max_drawdown(self, pnls: list[float]) -> float:
        cumulative = 0.0
        peak = 0.0
        max_dd = 0.0
        for pnl in pnls:
            cumulative += pnl
            if cumulative > peak:
                peak = cumulative
            drawdown = peak - cumulative
            if drawdown > max_dd:
                max_dd = drawdown
        return max_dd

    def _calculate_sharpe(self, pnls: list[float]) -> float:
        if len(pnls) < 2:
            return 0.0
        mean = sum(pnls) / len(pnls)
        variance = sum((p - mean) ** 2 for p in pnls) / (len(pnls) - 1)
        std = variance ** 0.5
        if std == 0:
            return 0.0
        # Annualize assuming ~250 trading days, ~3 trades/day
        return (mean / std) * (750 ** 0.5)

    def register_service(
        self,
        name: str,
        description: str,
        pricing: dict,
        metadata: dict,
    ) -> dict:
        """List the copy trading service on the marketplace."""
        return self._execute("register_service", {
            "agent_id": self.agent_id,
            "service_type": "copy_trading",
            "name": name,
            "description": description,
            "pricing": pricing,
            "metadata": metadata,
        })

    def configure_revenue(
        self,
        model: str = "hybrid",
        subscription_monthly_usd: str = "49.00",
        performance_fee_pct: str = "15.0",
        high_water_mark: bool = True,
    ) -> dict:
        """Configure revenue model for the copy trading service."""
        return {
            "model": model,
            "subscription_monthly_usd": subscription_monthly_usd,
            "performance_fee_pct": performance_fee_pct,
            "high_water_mark": high_water_mark,
        }
```

### Revenue Configuration: Fixed Fee vs Percentage vs Hybrid

Leaders choose from three revenue models. **Fixed subscription** charges a flat monthly fee regardless of performance -- predictable for both parties but does not align leader and follower incentives. **Performance fee** takes a percentage of profits above a high-water mark -- strongly aligns incentives but creates income volatility for the leader. **Hybrid** combines a lower monthly subscription with a reduced performance fee -- the subscription covers infrastructure costs while the performance fee rewards alpha. The hybrid model is the industry standard for copy trading services above $25/month.

```bash
# Register with hybrid pricing
curl -X POST https://sandbox.greenhelix.net/v1 \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "register_service",
    "input": {
      "agent_id": "leader-crypto-momentum-01",
      "service_type": "copy_trading",
      "name": "Crypto Momentum Alpha",
      "description": "Momentum strategy, BTC/ETH/SOL, Sharpe > 2.0",
      "pricing": {
        "model": "hybrid",
        "subscription_monthly_usd": "49.00",
        "performance_fee_pct": "15.0",
        "high_water_mark": true,
        "billing_cycle": "monthly",
        "trial_days": 7
      },
      "metadata": {
        "strategy_type": "momentum",
        "min_follower_capital_usd": "1000"
      }
    }
  }'
```

The `high_water_mark` flag ensures the leader only earns performance fees on new profits. If a follower's account drops from $10,000 to $8,000, the leader earns no performance fee until the account exceeds $10,000 again. This prevents leaders from earning fees on recovery -- you only pay for net new alpha.

### Trade Signal Broadcasting

When the leader executes a trade, the signal is normalized and broadcast to all followers via the GreenHelix event bus. The signal includes the symbol, side, size as a percentage of portfolio (not an absolute amount), and optional stop loss and take profit levels.

```python
import os

leader = CopyTradingLeader(
    api_key=os.environ["GREENHELIX_API_KEY"],
    agent_id="leader-crypto-momentum-01",
    private_key_b64=os.environ["LEADER_PRIVATE_KEY"],
)

# Long BTC with 10% of portfolio, 2% stop loss, 6% take profit
result = leader.broadcast_trade_signal(
    symbol="BTCUSDT",
    side="buy",
    size_pct=10.0,
    entry_price=67250.00,
    stop_loss=65905.00,
    take_profit=71285.00,
    order_type="limit",
    timeframe="4h",
)
print(f"Signal broadcast: {result}")

# Later, close the position
result = leader.close_position(
    signal_id=result["payload"]["signal_id"],
    exit_price=71100.00,
    pnl_pct=5.72,
)
print(f"Position closed: {result}")

# Submit updated performance metrics
metrics_result = leader.submit_performance_metrics()
print(f"Metrics submitted: {metrics_result}")
```

The `size_pct` field is the key abstraction that makes copy trading protocol-agnostic. A leader trading a $500K portfolio who allocates 10% to BTC sends `size_pct: 10.0`. A follower with a $5K portfolio allocates 10% -- $500 -- to the same trade. The signal describes intent, not execution details. Each follower's execution engine translates that intent into exchange-specific orders appropriate for their account size.

---

## Chapter 3: CopyTradingFollower Class

### Discovering and Evaluating Leaders

A follower's first task is finding leaders worth copying. The GreenHelix marketplace exposes leader listings through `search_services`, and the reputation engine provides verified metrics through `get_agent_reputation`. The combination lets followers make data-driven decisions rather than relying on platform-curated leaderboards.

```bash
# Search for copy trading leaders specializing in crypto momentum
curl -X POST https://sandbox.greenhelix.net/v1 \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "search_services",
    "input": {
      "service_type": "copy_trading",
      "query": "crypto momentum",
      "filters": {
        "min_sharpe": "1.5",
        "max_drawdown_pct": "20.0",
        "min_track_record_months": 6
      },
      "sort_by": "sharpe_ratio",
      "sort_order": "desc",
      "limit": 20
    }
  }'
```

```bash
# Get verified reputation for a specific leader
curl -X POST https://sandbox.greenhelix.net/v1 \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "get_agent_reputation",
    "input": {
      "agent_id": "leader-crypto-momentum-01"
    }
  }'
```

```bash
# Verify the leader's performance claim chain
curl -X POST https://sandbox.greenhelix.net/v1 \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "get_claim_chains",
    "input": {
      "agent_id": "leader-crypto-momentum-01",
      "claim_type": "performance_metrics"
    }
  }'
```

The claim chain is the critical verification step. `get_agent_reputation` returns aggregate scores, but `get_claim_chains` returns the Merkle tree of signed performance submissions. A follower can independently verify that each metric submission was signed by the leader's Ed25519 key, that the submissions form an unbroken chain, and that no submissions have been retroactively modified. This is the difference between "the platform says this leader has a 2.34 Sharpe" and "I have cryptographic proof that this leader submitted 18 months of signed performance data that produces a 2.34 Sharpe."

### The CopyTradingFollower Class

```python
import json
import time
import base64
import uuid
from datetime import datetime, timezone
from typing import Optional
from dataclasses import dataclass, field

import requests
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
    Ed25519PrivateKey,
    Ed25519PublicKey,
)
from cryptography.hazmat.primitives import serialization


@dataclass
class LeaderSubscription:
    """Tracks a follower's subscription to a specific leader."""
    leader_id: str
    escrow_id: str
    max_allocation_pct: float = 20.0
    max_drawdown_pct: float = 10.0
    max_position_size_pct: float = 5.0
    allowed_symbols: list[str] = field(default_factory=list)
    active: bool = True
    positions: dict = field(default_factory=dict)
    cumulative_pnl: float = 0.0
    high_water_mark: float = 0.0


class CopyTradingFollower:
    """Copy trading follower that discovers, evaluates, and copies leaders."""

    def __init__(
        self,
        api_key: str,
        agent_id: str,
        private_key_b64: str,
        portfolio_value_usd: float,
    ):
        self.api_base = "https://api.greenhelix.net/v1"
        self.api_key = api_key
        self.agent_id = agent_id
        self.portfolio_value = portfolio_value_usd
        self._private_key = Ed25519PrivateKey.from_private_bytes(
            base64.b64decode(private_key_b64)
        )
        self._subscriptions: dict[str, LeaderSubscription] = {}
        self._session = requests.Session()
        self._session.headers.update({
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        })

    def _execute(self, tool: str, input_data: dict) -> dict:
        resp = self._session.post(
            f"{self.api_base}/v1",
            json={"tool": tool, "input": input_data},
        )
        resp.raise_for_status()
        return resp.json()

    def _sign(self, payload: dict) -> str:
        canonical = json.dumps(payload, sort_keys=True, separators=(",", ":"))
        signature = self._private_key.sign(canonical.encode())
        return base64.b64encode(signature).decode()

    def discover_leaders(
        self,
        strategy_type: str = "momentum",
        min_sharpe: float = 1.5,
        max_drawdown: float = 20.0,
        min_months: int = 6,
    ) -> list[dict]:
        """Search for copy trading leaders matching criteria."""
        result = self._execute("search_services", {
            "service_type": "copy_trading",
            "query": strategy_type,
            "filters": {
                "min_sharpe": str(min_sharpe),
                "max_drawdown_pct": str(max_drawdown),
                "min_track_record_months": min_months,
            },
            "sort_by": "sharpe_ratio",
            "sort_order": "desc",
            "limit": 20,
        })
        return result.get("services", [])

    def evaluate_leader(self, leader_id: str) -> dict:
        """Get verified reputation and performance claim chain for a leader."""
        reputation = self._execute("get_agent_reputation", {
            "agent_id": leader_id,
        })
        claims = self._execute("get_claim_chains", {
            "agent_id": leader_id,
            "claim_type": "performance_metrics",
        })
        return {
            "reputation": reputation,
            "claim_chains": claims,
            "verified": self._verify_claim_chain(claims),
        }

    def _verify_claim_chain(self, claims: dict) -> bool:
        """Verify the integrity of a leader's performance claim chain."""
        chain = claims.get("chains", [])
        if not chain:
            return False
        # Verify each link is signed and the chain is unbroken
        for i, link in enumerate(chain):
            if "signature" not in link:
                return False
            if i > 0 and link.get("previous_hash") != chain[i - 1].get("hash"):
                return False
        return True

    def subscribe(
        self,
        leader_id: str,
        escrow_amount_usd: float,
        max_allocation_pct: float = 20.0,
        max_drawdown_pct: float = 10.0,
        max_position_size_pct: float = 5.0,
        allowed_symbols: Optional[list[str]] = None,
        evaluation_period_days: int = 30,
        performance_criteria: Optional[dict] = None,
    ) -> dict:
        """Subscribe to a leader with performance escrow protection."""
        if performance_criteria is None:
            performance_criteria = {
                "min_sharpe": "1.0",
                "max_drawdown_pct": "20.0",
                "min_win_rate_pct": "45.0",
            }

        escrow_result = self._execute("create_escrow", {
            "payer_id": self.agent_id,
            "payee_id": leader_id,
            "amount": str(escrow_amount_usd),
            "currency": "USD",
            "conditions": {
                "type": "performance_escrow",
                "evaluation_period_days": evaluation_period_days,
                "criteria": performance_criteria,
                "auto_release": True,
            },
            "description": f"Copy trading subscription: {self.agent_id} -> {leader_id}",
        })

        escrow_id = escrow_result["escrow_id"]

        subscription = LeaderSubscription(
            leader_id=leader_id,
            escrow_id=escrow_id,
            max_allocation_pct=max_allocation_pct,
            max_drawdown_pct=max_drawdown_pct,
            max_position_size_pct=max_position_size_pct,
            allowed_symbols=allowed_symbols or [],
        )
        self._subscriptions[leader_id] = subscription

        # Register webhook to receive trade signals from this leader
        self._execute("register_webhook", {
            "url": f"https://your-follower-bot.example.com/signals/{leader_id}",
            "event_types": ["copy_trade.signal", "copy_trade.close"],
            "filters": {"leader_id": leader_id},
            "secret": f"webhook-secret-{leader_id}",
        })

        return escrow_result

    def handle_trade_signal(self, signal: dict) -> Optional[dict]:
        """Process an incoming trade signal from a leader."""
        leader_id = signal.get("leader_id")
        sub = self._subscriptions.get(leader_id)
        if not sub or not sub.active:
            return None

        symbol = signal.get("symbol")

        # Check symbol whitelist
        if sub.allowed_symbols and symbol not in sub.allowed_symbols:
            return {"status": "skipped", "reason": "symbol_not_allowed"}

        # Check drawdown limit
        if sub.cumulative_pnl < 0 and abs(sub.cumulative_pnl) >= sub.max_drawdown_pct:
            sub.active = False
            return {"status": "stopped", "reason": "max_drawdown_reached"}

        # Check total allocation to this leader
        current_allocation = sum(
            pos.get("allocated_usd", 0) for pos in sub.positions.values()
        )
        max_allocation_usd = self.portfolio_value * (sub.max_allocation_pct / 100)
        if current_allocation >= max_allocation_usd:
            return {"status": "skipped", "reason": "max_allocation_reached"}

        # Calculate position size
        leader_size_pct = float(signal.get("size_pct", 0))
        capped_size_pct = min(leader_size_pct, sub.max_position_size_pct)
        position_usd = self.portfolio_value * (capped_size_pct / 100)

        # Ensure we do not exceed remaining allocation
        remaining = max_allocation_usd - current_allocation
        position_usd = min(position_usd, remaining)

        if position_usd < 10:  # Minimum position size
            return {"status": "skipped", "reason": "position_too_small"}

        # Execute the trade on the follower's exchange
        execution = self._execute_on_exchange(
            symbol=symbol,
            side=signal.get("side"),
            amount_usd=position_usd,
            order_type=signal.get("order_type", "market"),
            stop_loss=signal.get("stop_loss"),
            take_profit=signal.get("take_profit"),
        )

        signal_id = signal.get("signal_id")
        sub.positions[signal_id] = {
            "symbol": symbol,
            "side": signal.get("side"),
            "allocated_usd": position_usd,
            "entry_price": execution.get("fill_price"),
            "timestamp": signal.get("timestamp"),
        }

        return execution

    def handle_close_signal(self, signal: dict) -> Optional[dict]:
        """Process a position close signal from a leader."""
        leader_id = signal.get("leader_id")
        signal_id = signal.get("signal_id")
        sub = self._subscriptions.get(leader_id)
        if not sub or signal_id not in sub.positions:
            return None

        position = sub.positions[signal_id]
        execution = self._close_on_exchange(
            symbol=position["symbol"],
            side="sell" if position["side"] == "buy" else "buy",
            amount_usd=position["allocated_usd"],
        )

        # Track PnL
        pnl_pct = float(signal.get("pnl_pct", 0))
        sub.cumulative_pnl += pnl_pct
        if sub.cumulative_pnl > sub.high_water_mark:
            sub.high_water_mark = sub.cumulative_pnl

        del sub.positions[signal_id]
        return execution

    def _execute_on_exchange(self, **kwargs) -> dict:
        """Execute a trade on the follower's exchange. Override per exchange."""
        # Placeholder -- implement per exchange (Binance, Coinbase, etc.)
        return {
            "status": "filled",
            "fill_price": kwargs.get("amount_usd", 0),
            "exchange": "binance",
        }

    def _close_on_exchange(self, **kwargs) -> dict:
        """Close a position on the follower's exchange. Override per exchange."""
        return {"status": "closed", "exchange": "binance"}

    def unsubscribe(self, leader_id: str) -> dict:
        """Unsubscribe from a leader and close all open positions."""
        sub = self._subscriptions.get(leader_id)
        if not sub:
            return {"status": "not_subscribed"}

        # Close all open positions
        for signal_id, position in list(sub.positions.items()):
            self._close_on_exchange(
                symbol=position["symbol"],
                side="sell" if position["side"] == "buy" else "buy",
                amount_usd=position["allocated_usd"],
            )

        sub.active = False
        sub.positions.clear()

        return {"status": "unsubscribed", "leader_id": leader_id}
```

### Risk Limits Per Leader

The `LeaderSubscription` dataclass encodes four risk constraints that protect the follower:

**max_allocation_pct** -- The maximum percentage of the follower's portfolio that can be allocated to positions from this leader at any point in time. Default 20%. If a follower subscribes to five leaders at 20% each, their entire portfolio is allocated -- but no single leader can cause more than 20% damage.

**max_drawdown_pct** -- The cumulative loss threshold that triggers automatic unsubscription. If a leader's signals produce cumulative losses exceeding this threshold, the follower stops copying. Default 10%. This is a circuit breaker that prevents catastrophic losses from a leader who has lost their edge.

**max_position_size_pct** -- The maximum size of any single position, regardless of what the leader signals. If a leader allocates 25% of their portfolio to a single trade (aggressive), the follower caps it at 5% (conservative). This prevents a single bad trade from causing outsized damage.

**allowed_symbols** -- An optional whitelist of tradeable symbols. A follower might want to copy a leader's BTC and ETH trades but skip altcoin signals. An empty list means all symbols are allowed.

```python
import os

follower = CopyTradingFollower(
    api_key=os.environ["GREENHELIX_API_KEY"],
    agent_id="follower-conservative-01",
    private_key_b64=os.environ["FOLLOWER_PRIVATE_KEY"],
    portfolio_value_usd=25000.00,
)

# Subscribe to the momentum leader with conservative risk limits
escrow = follower.subscribe(
    leader_id="leader-crypto-momentum-01",
    escrow_amount_usd=500.00,
    max_allocation_pct=15.0,
    max_drawdown_pct=8.0,
    max_position_size_pct=3.0,
    allowed_symbols=["BTCUSDT", "ETHUSDT"],
    evaluation_period_days=30,
    performance_criteria={
        "min_sharpe": "1.5",
        "max_drawdown_pct": "15.0",
        "min_win_rate_pct": "50.0",
    },
)
print(f"Subscribed with escrow: {escrow['escrow_id']}")
```

This follower has a $25,000 portfolio and allocates at most 15% ($3,750) to the momentum leader. No single position exceeds 3% ($750). If cumulative losses reach 8% ($2,000), copying stops automatically. Only BTC and ETH signals are followed -- SOL is filtered out. The $500 escrow deposit is released to the leader only if they maintain a Sharpe above 1.5, drawdown below 15%, and win rate above 50% over 30 days.

---

## Chapter 4: Allocation Models

### Why One Size Does Not Fit All

A leader who allocates 15% of a $500K portfolio to a BTC long should not trigger the same $75K allocation from a $50K follower. The follower would be risking 150% of their capital. Even with `max_position_size_pct` caps, the relations

…(truncated)
