# Maxxit Lazy Trading

> Execute perpetual trades on Ostium, Aster, and Avantis via Maxxit's Lazy Trading API, and trade Indian stocks through Zerodha Kite. Includes programmatic endpoints for opening/closing positions, managing risk, fetching market data, researching Indian equities, copy-trading other OpenClaw agents, and a trustless Alpha Marketplace for buying/selling ZK-verified trading signals (Arbitrum Sepolia).

- Skill: `yejiming/maxxit-lazy-trading` (Agent Skill, multi-file: 12 files)
- Install (CLI): `npx skillmds@latest add yejiming/maxxit-lazy-trading`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yejiming/maxxit-lazy-trading/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: yejiming (https://skillmd.com/u/yejiming)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/yejiming/maxxit-lazy-trading

---


# Maxxit Lazy Trading

Execute perpetual futures trades on Ostium, Aster DEX, and Avantis DEX through Maxxit's Lazy Trading API. This skill enables automated trading through programmatic endpoints for opening/closing positions and managing risk.

## Built-in Strategy Scripts

The skill includes standalone Python strategy scripts. Use them when the user wants the agent to run a predefined trading system instead of manually specifying each trade.

- `ema-strategy.py`
  - Trend-following EMA crossover on Binance klines using close prices.
- `rsi-bollinger-strategy.py`
  - Mean-reversion system that waits for price to pierce a Bollinger Band and re-enter with RSI confirmation.
- `donchian-adx-strategy.py`
  - Breakout system that trades Donchian channel breaks only when ADX confirms a strong trend regime.
- `taker-strategy.py` - Aggressive Taker (Order Flow) HFT strategy. Analyzes Binance taker buy/sell ratios to detect aggressive market participants and catch rapid momentum shifts.
- `mean-reversion-strategy.py` - RSI + Bollinger Band mean-reversion strategy. A technical approach using price exhaustion points optimized for high-frequency scalping in sideways or boring markets.
- `breakout-strategy.py` - Volatility breakout strategy with ATR filter. Enters trades when price breaks out of a standard deviation channel while ATR confirms increasing volatility and momentum.
- `vwap-strategy.py` - VWAP crossover institutional momentum strategy. Uses volume-weighted average price and EMA to confirm institutional trend alignment and confirm trade strength with volume.

All scripts:
- read Binance kline data directly from `https://api.binance.com/api/v3/klines`
- use `MAXXIT_API_URL` and `MAXXIT_API_KEY`
- execute through Maxxit programmatic trading endpoints
- maintain per-symbol, per-venue state in the OpenClaw workspace

Example invocations:

```bash
python3 ema-strategy.py --symbol BTCUSDT --interval 5m --venue avantis
python3 rsi-bollinger-strategy.py --symbol ETHUSDT --interval 5m --venue ostium
python3 donchian-adx-strategy.py --symbol BTCUSDT --interval 15m --venue avantis
```

## When to Use This Skill

- User wants to execute trades on Ostium
- User wants to execute trades on Aster DEX
- User asks about their lazy trading account details
- User wants to check their USDC/ETH balance
- User wants to view their open positions or portfolio
- User wants to see their closed position history or PnL
- User wants to discover available trading symbols
- User wants market research, a market summary, or a trade-focused research brief
- User wants a whole market snapshot for the trading purpose
- User wants to open a new trading position (long/short)
- User wants to close an existing position
- User wants to set or modify take profit levels
- User wants to set or modify stop loss levels
- User wants to fetch current token/market prices
- User mentions "lazy trade", "perps", "perpetuals", or "futures trading"
- User wants to automate their trading workflow
- User wants to copy-trade or mirror another trader's positions
- User wants to discover other OpenClaw agents to learn from
- User wants to see what trades top-performing traders are making
- User wants to find high-impact-factor traders to replicate
- User wants to sell their trading signals as alpha
- User wants to browse or buy trustless alpha from ZK-verified traders
- User wants to generate a ZK proof of their trading performance or flag a position as alpha
- User mentions "alpha marketplace", "sell alpha", "buy alpha", or "ZK proof"

## Skill Maintenance

- If the user asks OpenClaw to update this skill, run:

```bash
npx clawhub@latest install maxxit-lazy-trading --force
```

---

## ⚠️ DEX Routing Rules (Mandatory)

1. **Always ask venue first if unclear**: "Do you want to trade on Ostium, Aster, or Avantis?"
2. **Always state the active venue explicitly** in your response (e.g., "Using Ostium..." or "Using Aster..." or "Using Avantis...").
3. **Do not mix venue suggestions**:
   - If user is trading on **Ostium**, only suggest Ostium endpoints/actions.
   - If user is trading on **Aster**, only suggest Aster endpoints/actions.
   - If user is trading on **Avantis**, only suggest Avantis endpoints/actions.
4. **Do not ask network clarification**:
   - **Ostium defaults to mainnet**, but if the user explicitly asks for **Ostium testnet / Arbitrum Sepolia**, honor that and pass `isTestnet: true` on Ostium endpoints.
   - **Aster is testnet-only** in this setup.
   - **Avantis is mainnet-only** (Base chain) in this setup.
   - Therefore do **not** ask "mainnet or testnet?" unless the user explicitly requests Ostium testnet.
5. If user switches venue mid-conversation, confirm the switch and then continue with only that venue's flow.

---

## ⚠️ CRITICAL: API Parameter Rules (Read Before Calling ANY Endpoint)

> **NEVER assume, guess, or hallucinate values for API request parameters.** Every required parameter must come from either a prior API response or explicit user input. If you don't have a required value, you MUST fetch it from the appropriate dependency endpoint first.

### Parameter Dependency Graph

The following shows where each required parameter comes from. **Always resolve dependencies before calling an endpoint.**

| Parameter | Source | Endpoint to Fetch From |
|-----------|--------|------------------------|
| `userAddress` / `address` | `/user-details` response → `user_wallet` | `GET /user-details` |
| `agentAddress` | `/user-details` response → `ostium_agent_address` | `GET /user-details` |
| `tradeIndex` | `/open-position` response → `actualTradeIndex` **OR** `/positions` response → `tradeIndex` | `POST /open-position` or `POST /positions` |
| `pairIndex` | `/positions` response → `pairIndex` **OR** `/symbols` response → symbol `id` | `POST /positions` or `GET /symbols` |
| `entryPrice` | `/open-position` response → `entryPrice` **OR** `/positions` response → `entryPrice` | `POST /open-position` or `POST /positions` |
| `market` / `symbol` | User specifies token **OR** `/symbols` response → `symbol` (e.g. `ETH/USD`) | User input or `GET /symbols` |
| `side` | User specifies `"long"` or `"short"` | User input (required) |
| `collateral` | User specifies the USDC amount | User input (required) |
| `leverage` | User specifies the multiplier | User input (required) |
| `takeProfitPercent` | User specifies (e.g., 0.30 = 30%) | User input (required) |
| `stopLossPercent` | User specifies (e.g., 0.10 = 10%) | User input (required) |
| `address` (for copy-trader-trades) | `/copy-traders` response → `creatorWallet` or `walletAddress` | `GET /copy-traders` |
| `commitment` (Alpha) | `/alpha/agents` response → `commitment` | `GET /alpha/agents` |
| `listingId` (Alpha) | `/alpha/listings` response → `listingId` | `GET /alpha/listings` |
| `alpha`, `contentHash` (Alpha) | `/alpha/purchase` Phase 2 response → `alpha`, `contentHash` | `GET /alpha/purchase` + `X-Payment` header |
| `txHash` (Alpha) | `/alpha/pay` response → `txHash` | `POST /alpha/pay` |

### Mandatory Workflow Rules

1. **Always call `/user-details` first** to get `user_wallet` (used as `userAddress`/`address`). Cache it for the session — it doesn't change.
2. **Treat `/user-details` as identity-first.** It always returns `user_wallet` for a valid API key, even if no lazy-trading agent exists yet.
3. **`/user-details` is sparse.** It omits fields that are empty, `null`, or `false`. Missing fields mean “not applicable” and should not be treated as an error or missing configuration by themselves.
4. **Only use `ostium_agent_address` when the venue needs an agent.** Ostium and Avantis require it. Zerodha does not. Aster only needs `user_wallet`, but `aster_configured` must be present and `true`.
5. **Never hardcode or guess wallet addresses.** They are unique per user and must come from `/user-details`.
6. **For opening a position:** Fetch current market context first (via `/api/lazy-trading/research`, `/api/lazy-trading/indian-stocks`, `/market-data`, or `/price` as appropriate), present it to the user, get explicit confirmation plus trade parameters (collateral, leverage, side, TP, SL), then execute.
   - **Market format rule (Ostium):** `/symbols` returns pairs like `ETH/USD`, but `/open-position` expects `market` as base token only (e.g. `ETH`). Convert by taking the base token before `/`.
7. **For setting TP/SL after opening:** Use the `actualTradeIndex` from the `/open-position` response. If you don't have it (e.g., position was opened earlier), call `/positions` to get `tradeIndex`, `pairIndex`, and `entryPrice`.
8. **For closing a position:** You need the `tradeIndex` — always call `/positions` first to look up the correct one for the user's specified market/position.
9. **Ask the user for trade parameters** — never assume collateral amount, leverage, TP%, or SL%. Present defaults but let the user confirm or override.
10. **Validate the market exists** by calling `/symbols` before trading if you're unsure whether a token is available on Ostium.
11. **For Alpha consumer flow:** Follow the exact order: `/alpha/agents` → `/alpha/listings` → `/alpha/purchase` (402) → `/alpha/pay` → `/alpha/purchase` (with `X-Payment`) → `/alpha/verify` → `/user-details` → `/alpha/execute`. Never skip steps. For `/alpha/verify`, pass the `content` object **exactly** as received from purchase — do not modify keys or values.

### Pre-Flight Checklist (Run Mentally Before Every API Call)

```
✅ Do I have the user's wallet address? → If not, call /user-details
✅ Does this flow require an agent address? → If yes, call /user-details and verify ostium_agent_address is present
✅ Does this endpoint need a tradeIndex? → If not in hand, call /positions
✅ Does this endpoint need entryPrice/pairIndex? → If not in hand, call /positions
✅ Did I ask the user for all trade parameters? → collateral, leverage, side, TP%, SL%
✅ Is the market/symbol valid? → If unsure, call /symbols to verify
✅ (Alpha) Do I have commitment? → If not, call /alpha/agents
✅ (Alpha) Do I have listingId? → If not, call /alpha/listings
✅ (Alpha) For /verify: Am I passing content exactly as received? → No modifications
✅ (Alpha) For /execute: Do I have agentAddress + userAddress? → Call /user-details
```

---

## Authentication

All requests require an API key with prefix `lt_`. Pass it via:
- Header: `X-API-KEY: lt_your_api_key`
- Or: `Authorization: Bearer lt_your_api_key`

## Market Research Workflow

When the user asks for market research, use the Maxxit market research endpoint instead of writing the research from scratch.

Endpoint:
- `POST /api/lazy-trading/research`
- `POST /api/lazy-trading/indian-stocks` for Indian equities research queries

Rules:
- Construct the `content` prompt from the user's ask.
- Preserve the user's asset, timeframe, strategy, and risk focus.
- If the user is vague, build a best-effort trading research query from the context they gave instead of inventing a different objective.
- Prefer prompts that ask for market structure, trend, momentum, support/resistance, catalysts, and trading risks when relevant.
- Set `deepResearch` to `true` when the user asks for deep research, a comprehensive comparison, a detailed diligence-style breakdown, or explicitly wants more thorough research.
- Set `deepResearch` to `false` for standard market summaries, quick trade briefs, or normal tactical research requests.
- For `POST /api/lazy-trading/indian-stocks`, OpenClaw must decide the request options from the user's query and should not ask the user to choose `chat_model`, `response_length`, or `thinking_level`.
- Always send `question` plus the inferred request options:
  - `chat_model`: `analytical` or `strategic`
  - `response_length`: `short`, `medium`, or `long`
  - `thinking_level`: only include this when `chat_model` is `strategic`
- Use `chat_model: "strategic"` when the user wants a trading plan, swing-trade setups, long/short ideas, entry zones, stop loss, target levels, timing for this week, or tactical positioning. In strategic mode, include `thinking_level` automatically:
  - use `balanced` by default
  - use `low` for quick, lightweight tactical asks
  - use `deep` only when the user explicitly asks for a more thoughtful or more detailed strategy answer
- Use `chat_model: "analytical"` for screens, rankings, fundamentals, valuation, sector comparisons, capex-cycle beneficiaries, earnings quality, balance sheet analysis, and diligence-style research. Do not send `thinking_level` in analytical mode.
- Infer `response_length` from the user’s ask:
  - use `short` for quick answers, concise trade ideas, and direct setup requests
  - use `medium` by default for normal research requests
  - use `long` for ranked lists, detailed comparisons, deep dives, or multi-factor explanations
- If the user’s wording contains both analytical and tactical elements, prioritize the main deliverable. If the answer must provide actionable trade setups, choose `strategic`; if the answer is mainly screening, ranking, valuation, or fundamental comparison, choose `analytical`.
- Summarize the response and format it for readability.

Prompt construction examples:
- User: "Research BTC for a swing long."
  - Query: `Analyze BTC for a swing-long setup. Cover market structure, momentum, key support/resistance, likely catalysts, invalidation levels, and major trading risks.`
- User: "Give me market research on ETH for today."
  - Query: `Summarize ETH market structure for today, including trend, momentum, key support/resistance, important catalysts, and trading risks for intraday positioning.`
- User: "Research SOL before I short it."
  - Query: `Analyze SOL for a potential short setup. Cover current market structure, weakness signals, resistance levels, downside levels to watch, catalysts, and key squeeze/invalidation risks.`

Example call:

```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/research" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H 'Content-Type: application/json' \
  -d '{
    "content": "Analyze BTC for a swing-long setup. Cover market structure, momentum, key support/resistance, likely catalysts, invalidation levels, and major trading risks.",
    "deepResearch": false
  }'
```

Indian stocks example:

```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/indian-stocks" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H 'Content-Type: application/json' \
  -d '{
    "question": "Screen for Indian IT stocks with strong profit growth and low debt.",
    "chat_model": "analytical",
    "response_length": "medium"
  }'
```

Indian stocks tactical example:

```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/indian-stocks" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H 'Content-Type: application/json' \
  -d '{
    "question": "Which Indian banking stocks look strongest for a swing trade this week? Give long ideas only, with entry zone, stop loss, target range, and the reasoning behind each setup.",
    "chat_model": "strategic",
    "response_length": "short",
    "thinking_level": "balanced"
  }'
```

When discussing Indian equities, NSE/BSE orders, holdings, targets, stop losses, or portfolio values:
- use **Indian rupees** as the default unit
- prefer `₹` in user-facing responses (for example, `₹2,450`, `₹1.2 lakh`)

## API Endpoints

## Ostium Programmatic Endpoints (`/api/lazy-trading/programmatic/*`)

> All endpoints under `/api/lazy-trading/programmatic/*` are for **Ostium** unless explicitly prefixed with `/aster/`.

### Get User Details

Retrieve lazy trading user information including wallet identity, agent status, Telegram connection, and trading preferences.

```bash
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/user-details" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}"
```

**Response:**
```json
{
  "success": true,
  "user_wallet": "0x...",
  "lazy_trading_ready": true,
  "agent": {
    "id": "agent-uuid",
    "name": "Lazy Trader - Username",
    "venue": "ostium",
    "status": "active"
  },
  "telegram_user": {
    "id": 123,
    "telegram_user_id": "123456789",
    "telegram_username": "trader"
  },
  "deployment": {
    "id": "deployment-uuid",
    "status": "active",
    "enabled_venues": ["ostium"]
  },
  "trading_preferences": {
    "risk_tolerance": "medium",
    "trade_frequency": "moderate"
  },
  "ostium_agent_address": "0x...",
  "aster_configured": true
}
```

If the user has not set up a lazy-trading agent yet, `/user-details` still returns `200` and identity data, for example:

```json
{
  "success": true,
  "user_wallet": "0x..."
}
```

### Get Available Symbols

Retrieve all available trading symbols from the Ostium exchange. Use this to discover which symbols you can trade.

```bash
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/symbols" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}"
```

**Response:**
```json
{
  "success": true,
  "symbols": [
    {
      "id": 0,
      "symbol": "BTC/USD",
      "group": "crypto",
      "maxLeverage": 150
    },
    {
      "id": 1,
      "symbol": "ETH/USD",
      "group": "crypto",
      "maxLeverage": 100
    }
  ],
  "groupedSymbols": {
    "crypto": [
      { "id": 0, "symbol": "BTC/USD", "group": "crypto", "maxLeverage": 150 },
      { "id": 1, "symbol": "ETH/USD", "group": "crypto", "maxLeverage": 100 }
    ],
    "forex": [...]
  },
  "count": 45
}
```

### Get Account Balance

Retrieve USDC and ETH balance for the user's Ostium wallet address.

> **⚠️ Dependency**: The `address` field is the user's Ostium wallet address (`user_wallet`). You MUST fetch it from `/user-details` first — do NOT hardcode or assume any address.

```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/balance" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d "{"address": "0x..."}"
```

**Response:**
```json
{
  "success": true,
  "address": "0x...",
  "usdcBalance": "1000.50",
  "ethBalance": "0.045"
}
```

### Get Portfolio Positions

Get all open positions for the user's Ostium trading account. **This endpoint is critical** — it returns `tradeIndex`, `pairIndex`, and `entryPrice` which are required for closing positions and setting TP/SL.

> **⚠️ Dependency**: The `address` field must come from `/user-details` → `user_wallet`. NEVER guess it.
>
> **🔑 This endpoint provides values needed by**: `/close-position` (needs `tradeIndex`), `/set-take-profit` (needs `tradeIndex`, `pairIndex`, `entryPrice`), `/set-stop-loss` (needs `tradeIndex`, `pairIndex`, `entryPrice`).

```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/positions" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d "{"address": "0x..."}"
```

**Request Body:**
```json
{
  "address": "0x..."  // REQUIRED — from /user-details → user_wallet. NEVER guess this.
}
```

**Response:**
```json
{
  "success": true,
  "positions": [
    {
      "market": "BTC",
      "marketFull": "BTC/USD",
      "side": "long",
      "collateral": 100.0,
      "entryPrice": 95000.0,
      "leverage": 10.0,
      "tradeId": "12345",
      "tradeIndex": 2,
      "pairIndex": "0",
      "notionalUsd": 1000.0,
      "totalFees": 2.50,
      "stopLossPrice": 85500.0,
      "takeProfitPrice": 0.0
    }
  ],
  "totalPositions": 1
}
```

> **Key fields to extract from each position:**
> - `tradeIndex` — needed for `/close-position`, `/set-take-profit`, `/set-stop-loss`
> - `pairIndex` — needed for `/set-take-profit`, `/set-stop-loss`
> - `entryPrice` — needed for `/set-take-profit`, `/set-stop-loss`
> - `side` — needed for `/set-take-profit`, `/set-stop-loss`
```

### Get Position History

Get trading history for a wallet.  
- `venue: "OSTIUM"` (default): uses Ostium history.
- `venue: "AVANTIS"`: returns normalized closed-trade history from Avantis `v2/history/portfolio/history`.

**Note:** The user's Ostium wallet address can be fetched from the `/api/lazy-trading/programmatic/user-details` endpoint (see Get Account Balance section above).

```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/history" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"venue":"OSTIUM","address":"0x...","count":50}'
```

**Request Body:**
```json
{
  "venue": "OSTIUM",    // Optional: "OSTIUM" (default) or "AVANTIS"
  "address": "0x...",   // Required for OSTIUM; also accepted for AVANTIS as alias of userAddress
  "count": 50           // Number of recent orders to retrieve (default: 50)
}
```

**Response:**
```json
{
  "success": true,
  "history": [
    {
      "market": "ETH",
      "side": "long",
      "collateral": 50.0,
      "leverage": 5,
      "price": 3200.0,
      "pnlUsdc": 15.50,
      "profitPercent": 31.0,
      "totalProfitPercent": 31.0,
      "rolloverFee": 0.05,
      "fundingFee": 0.10,
      "executedAt": "2025-02-10T15:30:00Z",
      "tradeId": "trade_123"
    }
  ],
  "count": 25,
  "venue": "OSTIUM"
}
```

**Avantis history example (same `/history` endpoint):**
```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/history" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"venue":"AVANTIS","userAddress":"0x...","count":50}'
```

Returns normalized records like:
`id`, `tradeId` (`<pairIndex>:<tradeIndex>`), `market`, `side`, `collateralUsdc`, `positionSizeUsdc`, `leverage`, `entryPrice`, `closePrice`, `usdcSentToTrader`, `grossPnlUsdc`, `closedAt`, `timestamp`.

### Open Position

Open a new perpetual futures position on Ostium.

> **⚠️ Dependencies — ALL must be resolved BEFORE calling this endpoint:**
> 1. `agentAddress` → from `/user-details` → `ostium_agent_address` (NEVER guess)
> 2. `userAddress` → from `/user-details` → `user_wallet` (NEVER guess)
> 3. `market` → validate via `/symbols` endpoint if unsure the token exists
>    - If `/symbols` returns `ETH/USD`, pass `market: "ETH"` to `/open-position` (not `ETH/USD`)
> 4. `side`, `collateral`, `leverage` → **ASK the user explicitly**, do not assume
>
> **📊 Recommended Pre-Trade Flow:**
> 1. Call `/api/lazy-trading/research` for crypto trade research, or `/market-data` / `/price` for current market conditions
> 2. Present the market context to the user (price, structure, momentum, volatility when available)
> 3. Ask the user: "Do you want to proceed? Specify: collateral (USDC), leverage, long/short"
> 4. Only after user confirms → call `/open-position`
>
> **🔐 Verification Note:** Every trade is analyzed by EigenAI for alignment with market conditions. Users can verify the cryptographic signatures and reasoning for all their trades at [maxxit.ai/openclaw](https://www.maxxit.ai/openclaw).
>
> **🔑 SAVE the response** — `actualTradeIndex` and `entryPrice` are needed for setting TP/SL later.

```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/open-position" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "agentAddress": "0x...",
    "userAddress": "0x...",
    "market": "BTC",
    "side": "long",
    "collateral": 100,
    "leverage": 10
  }'
```

**Request Body:**
```json
{
  "agentAddress": "0x...",      // REQUIRED — from /user-details → ostium_agent_address. NEVER guess.
  "userAddress": "0x...",       // REQUIRED — from /user-details → user_wallet. NEVER guess.
  "market": "BTC",              // REQUIRED — Base token only for Ostium (e.g. "ETH", not "ETH/USD"). Validate via /symbols if unsure.
  "side": "long",               // REQUIRED — "long" or "short". ASK the user.
  "collateral": 100,            // REQUIRED — Collateral in USDC. ASK the user.
  "leverage": 10,               // Optional (default: 10). ASK the user.
  "deploymentId": "uuid...",    // Optional — associated deployment ID
  "signalId": "uuid...",        // Optional — associated signal ID
  "isTestnet": false            // Optional. Set true only when user explicitly asks for Ostium testnet / Arbitrum Sepolia.
}
```

**Response (IMPORTANT — save these values):**
```json
{
  "success": true,
  "orderId": "order_123",
  "tradeId": "trade_abc",
  "transactionHash": "0x...",
  "txHash": "0x...",
  "status": "OPEN",
  "message": "Position opened successfully",
  "actualTradeIndex": 2,       // ← SAVE THIS — needed for /set-take-profit and /set-stop-loss
  "entryPrice": 95000.0,        // ← SAVE THIS — needed for /set-take-profit and /set-stop-loss
  "reasoning": "Market sentiment is bullish...", // EigenAI trade alignment analysis
  "llmSignature": "0x..."       // Cryptographic signature for auditability
}
```

### Close Position

Close an existing perpetual futures position on Ostium.

> **⚠️ Dependencies — resolve BEFORE calling this endpoint:**
> 1. `agentAddress` → from `/user-details` → `ostium_agent_address`
> 2. `userAddress` → from `/user-details` → `user_wallet`
> 3. `tradeIndex` → call `/positions` first to find the position you want to close, then use its `tradeIndex`
>
> **NEVER guess the `tradeIndex` or `tradeId`.** Always fetch from `/positions` endpoint.

```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/close-position" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "agentAddress": "0x...",
    "userAddress": "0x...",
    "market": "BTC",
    "tradeId": "12345"
  }'
```

**Request Body:**
```json
{
  "agentAddress": "0x...",      // REQUIRED — from /user-details → ostium_agent_address. NEVER guess.
  "userAddress": "0x...",       // REQUIRED — from /user-details → user_wallet. NEVER guess.
  "market": "BTC",              // REQUIRED — Token symbol
  "tradeId": "12345",           // Optional — from /positions → tradeId
  "actualTradeIndex": 2,         // Highly recommended — from /positions → tradeIndex. NEVER guess.
  "isTestnet": false            // Optional. Set true only when user explicitly asks for Ostium testnet / Arbitrum Sepolia.
}
```

**Response:**
```json
{
  "success": true,
  "result": {
    "txHash": "0x...",
    "market": "BTC",
    "closePnl": 25.50
  },
  "closePnl": 25.50,
  "message": "Position closed successfully",
  "alreadyClosed": false
}
```

### Set Take Profit

Set or update take-profit level for an existing position on Ostium.

> **⚠️ Dependencies — you need ALL of these before calling:**
> 1. `agentAddress` → from `/user-details` → `ostium_agent_address`
> 2. `userAddress` → from `/user-details` → `user_wallet`
> 3. `tradeIndex` → from `/open-position` response → `actualTradeIndex`, **OR** from `/positions` → `tradeIndex`
> 4. `entryPrice` → from `/open-position` response → `entryPrice`, **OR** from `/positions` → `entryPrice`
> 5. `pairIndex` → from `/positions` → `pairIndex`, **OR** from `/symbols` → symbol `id`
> 6. `takeProfitPercent` → **ASK the user** (default: 0.30 = 30%)
> 7. `side` → from `/positions` → `side` ("long" or "short")
>
> **If you just opened a position:** Use `actualTradeIndex` and `entryPrice` from the `/open-position` response.
> **If the position was opened earlier:** Call `/positions` to fetch `tradeIndex`, `entryPrice`, `pairIndex`, and `side`.

```bash
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/set-take-profit" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "agentAddress": "0x...",
    "userAddress": "0x...",
    "market": "BTC",
    "tradeIndex": 2,
    "takeProfitPercent": 0.30,
    "entryPrice": 90000,
    "pairIndex": 0
  }'
```

**Request Body:**
```json
{
  "agentAddress": "0x...",        // REQUIRED — from /user-details. NEVER guess.
  "userAddress": "0x...",         // REQUIRED — from /user-details. NEVER guess.
  "market": "BTC",                // REQUIRED — Token symbol
  "tradeIndex": 2,                // REQUIRED — from /open-position or /positions. NEVER guess.
  "takeProfitPercent": 0.30,       // Optional (default: 0.30 = 30%). ASK the user.
  "entryPrice": 90000,             // REQUIRED — from /open-position or /positions. NEVER guess.
  "pairIndex": 0,                  // REQUIRED — from /positions or /symbols. NEVER guess.
  "side": "long",                  // Optional (default: "long") — from /positions.
  "isTestnet": false              // Optional. Set true only when user explicitly asks for Ostium testnet / Arbitrum Sepolia.
}
```

**Response:**
```json
{
  "success": true,
  "message": "Take profit set successfully",
  "tpPrice": 117000.0
}
```

### Set Stop Loss

Set or update stop-loss level for an existing position on Ostium.

> **⚠️ Dependencies — identical to Set Take Profit. You need ALL of these before calling:**
> 1. `agentAddress` → from `/user-details` → `ostium_agent_address`
> 2. `userAddress` → from `/user-details` → `user_wallet`
> 3. `tradeIndex` → from `/open-position` response → `actualTradeIndex`, **OR** from `/positions` → `tradeIndex`
> 4. `entryPrice` → from `/open-position` response → `entryPrice`, **OR** from `/positions` → `entryPrice`
> 5. `pairIndex` → from `/positions` → `pairIndex`, **OR** from `/symbols` → symbol `id`
> 6. `stopLossPercent` → **ASK the user** (default: 0.10 = 10%)
> 7. `side` → from `/positions` → `side` ("long" or "short")
>
> **If you just opened a position:** Use `actualTradeIndex` and `entryPrice` from the `/open-position` response.
> **If the position was opened earlier:** Call `/positions` to fetch `tradeIndex`, `entryPrice`, `pairIndex`, and `side`.

```bash
# Same dependency resolution as Set Take Profit (see above for full example)
# Step 1: Get addresses from /user-details
# Step 2: Get position details from /positions
# Step 3: Set stop loss with user-specified stopLossPercent

curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/set-stop-loss" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "agentAddress": "0x...",
    "userAddress": "0x...",
    "market": "BTC",
    "tradeIndex": 2,
    "stopLossPercent": 0.10,
    "entryPrice": 90000,
    "pairIndex": 0,
    "side": "long"
  }'
```

**Request Body:**
```json
{
  "agentAddress": "0x...",        // REQUIRED — from /user-details. NEVER guess.
  "userAddress": "0x...",         // REQUIRED — from /user-details. NEVER guess.
  "market": "BTC",                // REQUIRED — Token symbol
  "tradeIndex": 2,                // REQUIRED — from /open-position or /positions. NEVER guess.
  "stopLossPercent": 0.10,         // Optional (default: 0.10 = 10%). ASK the user.
  "entryPrice": 90000,             // REQUIRED — from /open-position or /positions. NEVER guess.
  "pairIndex": 0,                  // REQUIRED — from /positions or /symbols. NEVER guess.
  "side": "long",                  // Optional (default: "long") — from /positions.
  "isTestnet": false              // Optional. Set true only when user explicitly asks for Ostium testnet / Arbitrum Sepolia.
}
```

**Response:**
```json
{
  "success": true,
  "message": "Stop loss set successfully",
  "slPrice": 81000.0,
  "liquidationPrice": 85500.0,
  "adjusted": false
}
```

### Get All Market Data

Retrieve the complete market snapshot from Ostium, including all symbols and their current metrics. This is useful for market-wide scanning or analysis in a single request.

```bash
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/market-data" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}"
```

**Response:**
```json
{
  "success": true,
  "data": [
    {
      "id": 0,
      "symbol": "BTC/USD",
      "group": "crypto",
      "maxLeverage": 150,
      "metrics": {
        "price": "95000.12345678",
        "percent_change_24h": 2.45,
        "volatility": 0.032,
        "volume_24h": "45000000000.00000000",
        "market_cap": "1850000000000.00000000"
      },
      "updated_at": "2026-02-14T08:30:00.000Z"
    },
    ...
  ],
  "count": 45
}
```

### Get Token Price

Fetch the current market price for a token from Ostium price feed.

```bash
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/price?token=BTC&isTestnet=false" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}"
```

**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|-------|----------|-------------|
| `token` | string | Yes | Token symbol to fetch price for (e.g., BTC, ETH, SOL) |
| `isTestnet` | boolean | No | Use Ostium testnet / Arbitrum Sepolia when explicitly requested by the user |

**Response:**
```json
{
  "success": true,
  "token": "BTC",
  "price": 95000.0,
  "isMarketOpen": true,
  "isDayTradingClosed": false
}
```

### Discover Traders to Copy (Copy Trading — Step 1)

Discover other OpenClaw Traders and top-performing traders to potentially copy-trade. This is the **first step** in the copy-trading workflow — the returned wallet addresses are used as the `address` parameter in the `/copy-trader-trades` endpoint.

> **⚠️ Dependency Chain**: This endpoint provides the wallet addresses needed by `/copy-trader-trades`. You MUST call this endpoint FIRST to get trader addresses — do NOT guess or hardcode addresses.
>
> **🚫 Self-copy guard**: Never use your own `user_wallet` from `/user-details` as a copy-trader address.

```bash
# Get all traders (OpenClaw + Leaderboard)
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/copy-traders" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}"

# Get only OpenClaw Traders (prioritized)
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/copy-traders?source=openclaw" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}"

# Get only Leaderboard traders with filters
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/copy-traders?source=leaderboard&minImpactFactor=50&minTrades=100" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}"
```

**Query Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `source` | string | `all` | `openclaw` (OpenClaw agents only), `leaderboard` (top traders only), `all` (both) |
| `limit` | int | 20 | Max results per tier (max 100) |
| `minTrades` | int | — | Min trade count filter (leaderboard only) |
| `minImpactFactor` | float | — | Min impact factor filter (leaderboard only) |

**Response:**
```json
{
  "success": true,
  "openclawTraders": [
    {
      "agentId": "3dbc322f-...",
      "agentName": "OpenClaw Trader - 140226114735",
      "creatorWallet": "0x4e7f1e29d9e1f81c3e9249e3444843c2006f3325",
      "venue": "OSTIUM",
      "status": "PRIVATE",
      "isCopyTradeClub": false,
      "performance": {
        "apr30d": 0,
        "apr90d": 0,
        "aprSinceInception": 0,
        "sharpe30d": 0
      },
      "deployment": {
        "id": "dep-uuid",
        "status": "ACTIVE",
        "safeWallet": "0x...",
        "isTestnet": true
      }
    }
  ],
  "topTraders": [
    {
      "walletAddress": "0xabc...",
      "totalVolume": "1500000.000000",
      "totalClosedVolume": "1200000.000000",
      "totalPnl": "85000.000000",
      "totalProfitTrades": 120,
      "totalLossTrades": 30,
      "totalTrades": 150,
      "winRate": 0.80,
      "lastActiveAt": "2026-02-15T10:30:00.000Z",
      "scores": {
        "edgeScore": 0.82,
        "consistencyScore": 0.75,
        "stakeScore": 0.68,
        "freshnessScore": 0.92,
        "impactFactor": 72.5
      },
      "updatedAt": "2026-02-17T06:00:00.000Z"
    }
  ],
  "openclawCount": 5,
  "topTradersCount": 20
}
```

**Key fields to use in next steps:**
- `openclawTraders[].creatorWallet` → use as `address` in `/copy-trader-trades`
- `topTraders[].walletAddress` → use as `address` in `/copy-trader-trades`
- Exclude any address equal to your own `/user-details.user_wallet`

### Get Trader's Recent Trades (Copy Trading — Step 2)

Fetch recent on-chain trades for a specific trader address. This queries the Ostium subgraph in real-time for fresh trade data.

> **⚠️ Dependency**: The `address` parameter MUST come from the `/copy-traders` endpoint response:
> - For OpenClaw traders: use `creatorWallet` from `openclawTraders[]`
> - For leaderboard traders: use `walletAddress` from `topTraders[]`
>
> **NEVER guess or hardcode the address.** Always call `/copy-traders` first.

```bash
# Step 1: Discover traders first
TRADER_ADDRESS=$(curl -s -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/copy-traders?source=openclaw" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}" | jq -r '.openclawTraders[0].creatorWallet')

# Step 2: Fetch their recent trades
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/copy-trader-trades?address=${TRADER_ADDRESS}" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}"

# With custom lookback and limit
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/copy-trader-trades?address=${TRADER_ADDRESS}&hours=48&limit=50" \
  -H "X-API-KEY: ${MAXXIT_API_KEY}"
```

**Query Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `address` | string | *required* | Trader wallet address (from `/copy-traders`) |
| `limit` | int | 20 | Max trades to return (max 50) |
| `hours` | int | 24 | Lookback window in hours (max 168 / 7 days) |

**Response:**
```json
{
  "success": true,
  "traderAddress": "0x4e7f1e29d9e1f81c3e9249e3444843c2006f3325",
  "trades": [
    {
      "tradeId": "0x123...",
      "side": "LONG",
      "tokenSymbol": "BTC",
      "pair": "BTC/USD",
      "collateral": 500.00,
      "leverage": 10.0,
      "entryPrice": 95000.50,
      "takeProfitPrice": 100000.00,
      "stopLossPrice": 90000.00,
      "timestamp": "2026-02-17T14:30:00.000Z"
    }
  ],
  "count": 5,
  "lookbackHours": 24
}
```

**Trade Field Descriptions:**
| Field | Description |
|-------|-------------|
| `side` | `"LONG"` or `"SHORT"` — the trade direction |
| `tokenSymbol` | Token being traded (e.g., `BTC`, `ETH`) |
| `pair` | Full pair label (e.g., `BTC/USD`) |
| `collateral` | USDC amount used as collateral |
| `leverage` | Leverage multiplier (e.g., 10.0 = 10x) |
| `entryPrice` | Price at which the trade was opened |
| `takeProfitPrice` | Take profit price (null if not set) |
| `stopLossPrice` | Stop loss price (null if not set) |
| `timestamp` | When the trade was opened |

> **Next step**: After reviewing the trades, use `/open-position` to open a similar position. You'll need your own `agentAddress` and `userAddress` from `/user-details`.

## Signal Format Examples

The lazy trading system processes natural language trading signals. Here are examples:

### Opening Positions
- `"Long ETH with 5x leverage, entry at 3200"`
- `"Short BTC 10x, TP 60000, SL 68000"`
- `"Buy 100 USDC worth of ETH perpetual"`

### With Risk Management
- `"Long SOL 3x leverage, entry 150, take profit 180, stop loss 140"`
- `"Short AVAX 5x, risk 2% of portfolio"`

### Closing Positions
- `"Close ETH long position"`
- `"Take profit on BTC short"`

---

## Complete Workflow Examples

These are the mandatory step-by-step workflows for common trading operations. **Follow these exactly.**

### Workflow 1: Opening a New Position (Full Flow)

```
Step 1: GET /user-details
   → Extract: user_wallet (→ userAddress), ostium_agent_address (→ agentAddress)
   → Cache these for the session

Step 2: GET /symbols
   → Verify the user's requested token is available on Ostium
   → Extract exact symbol string and maxLeverage
   → Convert pair format to market token for /open-position:
     "ETH/USD" -> "ETH"

Step 3: POST /api/lazy-trading/research  (or GET /market-data or GET /price for current context)
   → Get trade context: market structure, momentum, support/resistance, catalysts, and current price
   → Present this data to the user:
     "BTC is trading around $95,000 with bullish structure and clear support/resistance levels.
      Do you want to proceed?"

Step 4: ASK the user for trade parameters
   → "Please confirm: collateral (USDC), leverage, long or short?"
   → "Would you like to set TP and SL? If so, what percentages?"
   → Wait for explicit user confirmation before proceeding

Step 5: POST /open-position
   → Use agentAddress and userAddress from Step 1
   → Use market, side, collateral, leverage from Step 

…(truncated)
