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.
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.pyrsi-bollinger-strategy.pydonchian-adx-strategy.pytaker-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:
https://api.binance.com/api/v3/klinesMAXXIT_API_URL and MAXXIT_API_KEYExample invocations:
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
npx clawhub@latest install maxxit-lazy-trading --force
isTestnet: true on Ostium endpoints.> 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.
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 |
/user-details first to get user_wallet (used as userAddress/address). Cache it for the session — it doesn't change./user-details as identity-first. It always returns user_wallet for a valid API key, even if no lazy-trading agent exists yet./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.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./user-details./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./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 /.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.tradeIndex — always call /positions first to look up the correct one for the user's specified market/position./symbols before trading if you're unsure whether a token is available on Ostium./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.✅ 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
All requests require an API key with prefix lt_. Pass it via:
X-API-KEY: lt_your_api_keyAuthorization: Bearer lt_your_api_keyWhen the user asks for market research, use the Maxxit market research endpoint instead of writing the research from scratch.
Endpoint:
POST /api/lazy-trading/researchPOST /api/lazy-trading/indian-stocks for Indian equities research queriesRules:
content prompt from the user's ask.deepResearch to true when the user asks for deep research, a comprehensive comparison, a detailed diligence-style breakdown, or explicitly wants more thorough research.deepResearch to false for standard market summaries, quick trade briefs, or normal tactical research requests.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.question plus the inferred request options:chat_model: analytical or strategicresponse_length: short, medium, or longthinking_level: only include this when chat_model is strategicchat_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:balanced by defaultlow for quick, lightweight tactical asksdeep only when the user explicitly asks for a more thoughtful or more detailed strategy answerchat_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.response_length from the user’s ask:short for quick answers, concise trade ideas, and direct setup requestsmedium by default for normal research requestslong for ranked lists, detailed comparisons, deep dives, or multi-factor explanationsstrategic; if the answer is mainly screening, ranking, valuation, or fundamental comparison, choose analytical.Prompt construction examples:
Analyze BTC for a swing-long setup. Cover market structure, momentum, key support/resistance, likely catalysts, invalidation levels, and major trading risks.Summarize ETH market structure for today, including trend, momentum, key support/resistance, important catalysts, and trading risks for intraday positioning.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:
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:
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:
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:
₹ in user-facing responses (for example, ₹2,450, ₹1.2 lakh)/api/lazy-trading/programmatic/*)> All endpoints under /api/lazy-trading/programmatic/* are for Ostium unless explicitly prefixed with /aster/.
Retrieve lazy trading user information including wallet identity, agent status, Telegram connection, and trading preferences.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/user-details" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
Response:
{
"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:
{
"success": true,
"user_wallet": "0x..."
}
Retrieve all available trading symbols from the Ostium exchange. Use this to discover which symbols you can trade.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/symbols" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
Response:
{
"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
}
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.
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:
{
"success": true,
"address": "0x...",
"usdcBalance": "1000.50",
"ethBalance": "0.045"
}
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).
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:
{
"address": "0x..." // REQUIRED — from /user-details → user_wallet. NEVER guess this.
}
Response:
{
"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).
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:**
{
"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:**
{
"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):**
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.
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:**
{
"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):**
{
"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.
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:**
{
"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:**
{
"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`.
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:**
{
"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:**
{
"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`.
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:**
{
"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:**
{
"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.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/market-data" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
**Response:**
{
"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.
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:**
{
"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.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/copy-traders" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/copy-traders?source=openclaw" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
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:**
{
"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.
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')
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/copy-trader-trades?address=${TRADER_ADDRESS}" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
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:**
{
"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 4
→ IMPORTANT: Pass market as base token only (e.g. ETH), not pair format (ETH/USD)
→ SAVE the response: actualTradeIndex and entryPrice
Step 6 (if user wants TP/SL): POST /set-take-profit and/or POST /set-stop-loss
→ Use tradeIndex = actualTradeIndex from Step 5
→ Use entryPrice from Step 5
→ For pairIndex, use the symbol id from Step 2 or call /positions
→ Use takeProfitPercent/stopLossPercent from Step 4
Step 7: ASK — "Would you like to list this trade as alpha on the marketplace?"
→ If user says NO → Done.
→ If user says YES → Continue to Step 8.
→ Also ask: "What price in USDC would you like to charge?" (e.g. 5 USDC)
Step 8: POST /alpha/generate-proof
→ Body: { "tradeId": "{tradeId from Step 5}", "autoProcess": false }
→ tradeId comes from the /open-position response
→ autoProcess: false queues the proof for the worker (~3-5 min)
→ SAVE: proofId from the response
Step 9: Wait for proof verification
→ If autoProcess was true and response has status: "VERIFIED" → go to Step 10
→ If autoProcess was false or status is still PENDING/PROVING:
Poll GET /alpha/proof-status?proofId={proofId} every 10 seconds
→ Wait until status === "VERIFIED"
→ If status === "FAILED" → inform the user and stop
Step 10: POST /alpha/flag
→ Body: {
"proofId": "{proofId from Step 8}",
"priceUsdc": {price from Step 7},
"token": "{market from Step 5, e.g. ETH}",
"side": "{side from Step 5, e.g. long}",
"leverage": {leverage from Step 5}
}
→ Show user the response: listingId, tradeId, proofMetrics
→ "Your trade is now listed as alpha! Listing ID: {listingId}"
### Workflow 2: Closing an Existing Position
Step 1: GET /user-details
→ Extract: user_wallet, ostium_agent_address
Step 2: POST /positions (address = user_wallet from Step 1)
→ List all open positions
→ Present them to the user if multiple: "You have 3 open positions: BTC long, ETH short, SOL long. Which one do you want to close?"
→ Extract the tradeIndex for the position to close
Step 3: POST /close-position
→ Use agentAddress and userAddress from Step 1
→ Use market and actualTradeIndex from Step 2
→ Show the user the closePnl from the response
### Workflow 3: Setting TP/SL on an Existing Position
Step 1: GET /user-details
→ Extract: user_wallet, ostium_agent_address
Step 2: POST /positions (address = user_wallet from Step 1)
→ Find the target position
→ Extract: tradeIndex, entryPrice, pairIndex, side
Step 3: ASK the user
→ "Position: BTC long at $95,000. Current TP: none, SL: $85,500."
→ "What TP% and SL% would you like to set?"
Step 4: POST /set-take-profit and/or POST /set-stop-loss
→ Use ALL values from Steps 1-3 — NEVER guess any of them
### Workflow 4: Checking Portfolio & Market Overview
Step 1: GET /user-details
→ Extract: user_wallet
Step 2: POST /balance (address = user_wallet)
→ Show the user their USDC and ETH balances
Step 3: POST /positions (address = user_wallet)
→ Show all open positions with PnL details
Step 4 (optional): GET /market-data
→ Show market conditions for tokens they hold
### Workflow 5: Copy-Trading Another OpenClaw Agent (Full Flow)
Step 1: GET /copy-traders?source=openclaw
→ Discover other OpenClaw Trader agents
→ Extract: creatorWallet from the trader you want to copy
→ Exclude your own wallet (/user-details.user_wallet) if it appears
→ IMPORTANT: This is a REQUIRED first step — you cannot call
/copy-trader-trades without an address from this endpoint
Step 2: GET /copy-trader-trades?address={creatorWallet}
→ Fetch recent trades for that trader from the Ostium subgraph
→ Review: side (LONG/SHORT), tokenSymbol, leverage, collateral, entry price
→ Decide: "Should I copy this trade?"
→ DEPENDENCY: The address param comes from Step 1 (creatorWallet or walletAddress)
Step 3: GET /user-details
→ Get YOUR OWN userAddress (user_wallet) and agentAddress (ostium_agent_address)
→ These are needed to execute your own trade
Step 4: POST /open-position
→ Mirror the trade from Step 2 using your own addresses from Step 3:
→ SAVE: actualTradeIndex and entryPrice from response
Step 5 (optional): POST /set-take-profit and/or POST /set-stop-loss
→ Use actualTradeIndex and entryPrice from Step 4
→ Match the copied trader's TP/SL ratios or set your own
**Dependency Chain Summary:**
/copy-traders → provides address → /copy-trader-trades → provides trade details
/user-details → provides your addresses → /open-position → copies the trade
---
## Automated Trading Strategies
Maxxit provides specialized scripts for different market conditions. These scripts require dynamic parameters passed via command line.
### Execution Policy
- **Dynamic Arguments**: Scripts MUST be invoked with `--symbol` and `--venue`.
- **Agent Responsibility**: If the user asks to start a strategy but does not provide the symbol (e.g., "BTC/USD") or the venue (e.g., "AVANTIS"), the agent MUST ask the user for the missing information before executing the script.
- **Example Command**: `python taker-strategy.py --symbol BTC/USD --venue AVANTIS`
### 1. Aggressive Taker (HFT / Order Flow)
- **Script**: `taker-strategy.py`
- **Usage**: `python taker-strategy.py --symbol <SYMBOL> --venue <VENUE>`
- **Logic Summary**: Monitors the "Taker Buy Ratio" on Binance. When aggressive buyers (takers) dominate sellers beyond a threshold (0.60), it signals a high-conviction momentum move.
- **Best For**: Capturing rapid price changes in high-volume environments (Active Scalping).
### 2. Mean Reversion (Sideways / Range)
- **Script**: `mean-reversion-strategy.py`
- **Usage**: `python mean-reversion-strategy.py --symbol <SYMBOL> --venue <VENUE>`
- **Logic Summary**: Combines RSI (extreme oversold/overbought) with Bollinger Band touches. It identifies "exhaustion" points where the price is likely to bounce back to the average.
- **Best For**: Range-bound or sideways markets where there is no clear trend.
### 3. Volatility Breakout (Momentum)
- **Script**: `breakout-strategy.py`
- **Usage**: `python breakout-strategy.py --symbol <SYMBOL> --venue <VENUE>`
- **Logic Summary**: Enters a trade only when price breaks out of a standard deviation channel (Bollinger Bands) *and* volatility (ATR) is increasing. This filters out "fake" breakouts.
- **Best For**: Catching the start of a strong trend after a period of consolidation.
### 4. VWAP Crossover (Institutional Momentum)
- **Script**: `vwap-strategy.py`
- **Usage**: `python vwap-strategy.py --symbol <SYMBOL> --venue <VENUE>`
- **Logic Summary**: Uses Volume Weighted Average Price (VWAP) combined with a 20 EMA. A "Long" is triggered when price is above both the VWAP and the EMA, signaling that both volume and time-weighted momentum are positive.
- **Best For**: Intraday momentum trading and confirming trend strength with volume.
---
## Aster DEX (BNB Chain) Endpoints
> Aster DEX is a perpetual futures exchange on BNB Chain. Use Aster endpoints when the user wants to trade on BNB Chain. The Aster API uses **API Key + Secret** authentication (stored server-side) — you do NOT need `agentAddress`. You only need `userAddress` from `/user-details`.
### Venue Selection
| Venue | Chain | Symbol Format | Auth Required | When to Use |
|-------|-------|--------------|---------------|-------------|
| **Ostium** | Arbitrum (mainnet by default, testnet on explicit request) | `BTC`, `ETH` | `agentAddress` + `userAddress` | Default for most trades |
| **Aster** | BNB Chain (testnet only) | `BTCUSDT`, `ETHUSDT` | `userAddress` only | When user specifies BNB Chain or Aster |
| **Avantis** | Base (mainnet only) | Base token for orders (e.g. `BTC`), pair format in symbols/positions (e.g. `BTC/USD`) | `agentAddress` + `userAddress` | When user specifies Base chain or Avantis |
> **Network behavior rule:** Do not ask users to choose mainnet/testnet for these venues by default. Ostium uses mainnet unless the user explicitly asks for testnet / Arbitrum Sepolia. Aster is fixed to testnet, and Avantis is fixed to Base mainnet.
**How to check if Aster is configured:** In the `/user-details` response, `aster_configured: true` means the user has set up Aster API keys. If `false`, direct them to set up Aster at maxxit.ai/openclaw.
### Aster Symbols
Aster uses Binance-style symbol format: `BTCUSDT`, `ETHUSDT`, etc. The API auto-appends `USDT` if you pass just `BTC`.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/symbols" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
**Response:**
{
"success": true,
"symbols": [
{
"symbol": "BTCUSDT",
"baseAsset": "BTC",
"quoteAsset": "USDT",
"pricePrecision": 2,
"quantityPrecision": 3,
"contractType": "PERPETUAL",
"status": "TRADING"
}
],
"count": 50
}
### Aster Price
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/price?token=BTC" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
**Response:**
{
"success": true,
"token": "BTC",
"symbol": "BTCUSDT",
"price": 95000.50
}
### Aster Market Data
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/market-data?symbol=BTC" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
### Aster Balance
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/balance" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x..."
}'
**Request Body:**
{
"userAddress": "0x..." // REQUIRED — from /user-details → user_wallet. NEVER guess.
}
**Response:**
{
"success": true,
"balance": 1000.50,
"availableBalance": 800.25,
"unrealizedProfit": 50.10
}
### Aster Positions
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/positions" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x..."
}'
**Response:**
{
"success": true,
"positions": [
{
"symbol": "BTCUSDT",
"positionAmt": 0.01,
"entryPrice": 95000.0,
"markPrice": 96000.0,
"unrealizedProfit": 10.0,
"liquidationPrice": 80000.0,
"leverage": 10,
"side": "long"
}
],
"count": 1
}
### Aster History (All Orders)
Fetch full order history for a symbol (includes active, canceled, and filled orders) from Aster.
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/history" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x...",
"symbol": "BTC",
"limit": 100
}'
**Request Body:**
{
"userAddress": "0x...", // REQUIRED — from /user-details → user_wallet
"symbol": "BTC", // REQUIRED — token or full symbol (BTC or BTCUSDT)
"limit": 100, // Optional — default depends on exchange (max 1000)
"orderId": 12345, // Optional — fetch from this orderId onward
"startTime": 1709251200000, // Optional — ms timestamp
"endTime": 1709856000000 // Optional — ms timestamp
}
> `POST /api/lazy-trading/programmatic/aster/history` now proxies to Aster `/fapi/v3/allOrders`.
> Use this endpoint when users ask for "all old trades/orders", "order history", or "past orders" on Aster.
### Aster Open Position
> **📋 LLM Pre-Call Checklist — Ask the user these questions before calling this endpoint:**
> 1. **Symbol**: "Which token do you want to trade?" (e.g. BTC, ETH, SOL)
> 2. **Side**: "Long or short?"
> 3. **Quantity**: "How much [TOKEN] do you want to trade?" — get the answer in base asset units (e.g. `0.01 BTC`, `0.5 ETH`).
> 4. **Leverage**: "What leverage? (e.g. 10x)"
> 5. **Order type**: "Market order or limit order?" (default: MARKET). If LIMIT, also ask for the limit price.
>
> **Aster requires `quantity` (base asset) for open-position. Do not use collateral.**
> **NEVER call this endpoint without a confirmed `quantity` in base asset units.**
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/open-position" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x...",
"symbol": "BTC",
"side": "long",
"quantity": 0.01,
"leverage": 10
}'
**Request Body:**
{
"userAddress": "0x...", // REQUIRED — from /user-details → user_wallet. NEVER guess.
"symbol": "BTC", // REQUIRED — Token name or full symbol (BTCUSDT). ASK the user.
"side": "long", // REQUIRED — "long" or "short". ASK the user.
"quantity": 0.01, // REQUIRED — Position size in BASE asset (e.g. 0.01 BTC). ASK the user.
"leverage": 10, // Optional — Leverage multiplier. ASK the user.
"type": "MARKET", // Optional — "MARKET" (default) or "LIMIT". ASK the user.
"price": 95000 // Required only for LIMIT orders. ASK the user if type is LIMIT.
}
> ⚠️ **IMPORTANT:** `quantity` must always be specified in the **base asset** (e.g. `0.01` for 0.01 BTC).
> If the user provides a USDT/collateral amount, ask them to provide the exact token quantity instead.
> Do not convert collateral to quantity in this workflow.
**Response (IMPORTANT — save these values):**
{
"success": true,
"orderId": 12345678,
"symbol": "BTCUSDT",
"side": "BUY",
"status": "FILLED",
"avgPrice": "95000.50",
"executedQty": "0.010",
"message": "Position opened: long BTCUSDT"
}
### Aster Close Position
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/close-position" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x...",
"symbol": "BTC"
}'
**Request Body:**
{
"userAddress": "0x...", // REQUIRED
"symbol": "BTC", // REQUIRED
"quantity": 0.005 // Optional — omit to close full position
}
### Aster Set Take Profit
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/set-take-profit" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x...",
"symbol": "BTC",
"takeProfitPercent": 0.30,
"entryPrice": 95000,
"side": "long"
}'
**Request Body (two options):**
{
"userAddress": "0x...",
"symbol": "BTC",
"stopPrice": 123500 // Option A: exact trigger price
}
{
"userAddress": "0x...",
"symbol": "BTC",
"takeProfitPercent": 0.30, // Option B: percentage (0.30 = 30%)
"entryPrice": 95000,
"side": "long"
}
### Aster Set Stop Loss
Same pattern as take profit:
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/set-stop-loss" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x...",
"symbol": "BTC",
"stopLossPercent": 0.10,
"entryPrice": 95000,
"side": "long"
}'
### Aster Change Leverage
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/aster/change-leverage" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x...",
"symbol": "BTC",
"leverage": 20
}'
### Aster Parameter Dependency Graph
| Parameter | Source | How to Get |
|-----------|--------|-----------|
| `userAddress` | `/user-details` → `user_wallet` | `GET /user-details` |
| `aster_configured` | `/user-details` → `aster_configured` | `GET /user-details` (must be `true`) |
| `symbol` | User specifies token | User input (auto-resolved: `BTC` → `BTCUSDT`) |
| `side` | User specifies `"long"` or `"short"` | User input (required) |
| `quantity` | User specifies in base asset units (e.g. `0.01 BTC`) | User input (required). If user provides USDT/collateral amount, ask for quantity instead. Do not calculate in the workflow. |
| `leverage` | User specifies | User input |
| `entryPrice` | `/aster/positions` → `entryPrice` | From position data |
| `stopPrice` | User specifies or calculated from percent | User input or calculated |
### Aster Workflow: Open Position on BNB Chain
Step 1: GET /user-details
→ Extract: user_wallet
→ Check: aster_configured == true (if false, tell user to set up Aster at maxxit.ai/openclaw)
Step 2: GET /aster/symbols
→ Verify the token is available on Aster
Step 3: GET /aster/price?token=BTC
→ Get current price, present to user
Step 4: ASK the user for ALL trade parameters
→ "Which token?" (e.g. BTC, ETH, SOL)
→ "Long or short?"
→ "How much [TOKEN] do you want to buy/sell?" — collect answer in BASE asset units (e.g. 0.01 BTC)
• If user gives a USDT/collateral amount, ask them to provide token quantity instead.
→ "Leverage? (e.g. 10x)"
→ "Market or limit order?" — if LIMIT, also ask for the limit price
Step 5: POST /aster/open-position
→ Use userAddress from Step 1
→ Use symbol, side, quantity (base asset), leverage from Step 4
→ SAVE orderId and avgPrice from response
Step 6 (if user wants TP/SL): POST /aster/set-take-profit and/or POST /aster/set-stop-loss
→ Use entryPrice = avgPrice from Step 5
→ Use side from Step 4
→ Ask user for takeProfitPercent / stopLossPercent (or exact stopPrice)
### Aster Workflow: Close Position
Step 1: GET /user-details → Extract user_wallet
Step 2: POST /aster/positions (userAddress = user_wallet)
→ Show positions to user, let them pick which to close
Step 3: POST /aster/close-position
→ Pass userAddress and symbol
→ Omit quantity to close full position
---
## Avantis DEX (Base Chain) Endpoints
> Avantis DEX is a perpetual futures exchange on Base chain. Use Avantis endpoints when the user wants to trade on Base. Avantis uses **delegation-based auth** (same pattern as Ostium) — you need both `agentAddress` and `userAddress` from `/user-details`.
**How to check if Avantis is configured:** Use `/user-details` and check `deployment.enabled_venues`. If it includes `"AVANTIS"`, Avantis is enabled for the current deployment. If not, direct the user to enable Avantis at maxxit.ai/openclaw.
### Avantis Symbols
Avantis symbols are returned in pair format (e.g. `BTC/USD`, `ETH/USD`). The API endpoint maps the service's `/markets` route.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/avantis/symbols" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
**Response:**
{
"success": true,
"markets": [
{
"pairIndex": 0,
"symbol": "BTC/USD",
"group": "crypto"
},
{
"pairIndex": 1,
"symbol": "ETH/USD",
"group": "crypto"
}
],
"count": 50
}
### Avantis Get Token Price
Fetch the latest price for a specific token on Avantis.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/avantis/price?token=BTC" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `token` | string | Yes | Token symbol or pair (e.g. `BTC` or `BTC/USD`) |
**Response:**
{
"success": true,
"token": "BTC",
"market": "BTC/USD",
"pairIndex": 0,
"price": 95000.12
}
### Avantis Balance
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/avantis/balance" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x..."
}'
**Request Body:**
{
"userAddress": "0x..." // REQUIRED — from /user-details → user_wallet. NEVER guess.
}
**Response:**
{
"success": true,
"usdcBalance": "1500.25",
"ethBalance": "0.05"
}
### Avantis Positions
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/avantis/positions" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"userAddress": "0x...",
"agentAddress": "0x..."
}'
**Response:**
{
"success": true,
"positions": [
{
"market": "BTC/USD",
"marketFull": "BTC/USD",
"side": "long",
"collateral": 100.0,
"entryPrice": 95000.0,
"leverage": 10.0,
"tradeId": "0:2",
"tradeIndex": 2,
"pairIndex": 0
}
],
"totalPositions": 1
}
### Avantis Open Position
> **⚠️ Dependencies:**
> 1. `agentAddress` → from `/user-details` → `ostium_agent_address` (shared agent wallet; NEVER guess)
> 2. `userAddress` → from `/user-details` → `user_wallet` (NEVER guess)
> 3. `market` → validate via `/avantis/symbols`. Use base token only (e.g. `BTC`, not `BTC/USD`)
> 4. `side`, `collateral`, `leverage` → **ASK the user explicitly**
>
> **Avantis uses `collateral` (USDC amount), similar to Ostium.**
>
> **TP/SL can be set at open (`takeProfitPercent` / `stopLossPercent`) or updated later via `/avantis/update-sl-tp`.**
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/avantis/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,
"takeProfitPercent": 0.30,
"stopLossPercent": 0.10
}'
**Request Body:**
{
"agentAddress": "0x...", // REQUIRED — from /user-details → ostium_agent_address (shared wallet). NEVER guess.
"userAddress": "0x...", // REQUIRED — from /user-details → user_wallet. NEVER guess.
"market": "BTC", // REQUIRED — Base token only (e.g. "ETH", not "ETH/USD")
"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.
"takeProfitPercent": 0.30, // Optional — set TP at open. ASK the user.
"stopLossPercent": 0.10 // Optional — set SL at open. ASK the user.
}
**Response:**
{
"success": true,
"txHash": "0x...",
"actualTradeIndex": 5,
"entryPrice": 95000.0,
"slSet": true,
"tpSet": true,
"message": "Trade submitted on Avantis",
"result": {
"market": "BTC",
"side": "long",
"collateral": 100,
"leverage": 10,
"slConfigured": true,
"tpConfigured": true,
"tpPrice": 123500.0,
"slPrice": 85500.0
}
}
### Avantis Close Position
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/avantis/close-position" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"agentAddress": "0x...",
"userAddress": "0x...",
"market": "BTC"
}'
**Request Body:**
{
"agentAddress": "0x...", // REQUIRED — from /user-details. NEVER guess.
"userAddress": "0x...", // REQUIRED — from /user-details. NEVER guess.
"market": "BTC", // REQUIRED — Token symbol
"tradeId": "0:2", // Optional — preferred composite ID from /avantis/positions (pairIndex:tradeIndex)
"actualTradeIndex": 2 // Recommended — from /avantis/positions → tradeIndex
}
### Avantis Update SL/TP
> **TP/SL can be set at open time (via `takeProfitPercent`/`stopLossPercent` in open-position), or updated after opening using this endpoint.**
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/avantis/update-sl-tp" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"agentAddress": "0x...",
"userAddress": "0x...",
"market": "BTC",
"takeProfitPercent": 0.30,
"stopLossPercent": 0.10
}'
**Request Body:**
{
"agentAddress": "0x...", // REQUIRED — from /user-details. NEVER guess.
"userAddress": "0x...", // REQUIRED — from /user-details. NEVER guess.
"market": "BTC", // REQUIRED — Token symbol
"tradeIndex": 0, // Optional — specific trade index from /avantis/positions
"takeProfitPrice": 100000, // Absolute TP price (use this OR takeProfitPercent)
"stopLossPrice": 80000, // Absolute SL price (use this OR stopLossPercent)
"takeProfitPercent": 0.30, // TP as % from entry (0.30 = 30%). Use this OR takeProfitPrice.
"stopLossPercent": 0.10 // SL as % from entry (0.10 = 10%). Use this OR stopLossPrice.
}
**Response:**
{
"success": true,
"txHash": "0x...",
"message": "TP/SL updated successfully",
"result": {
"market": "BTC",
"tradeIndex": 0,
"entryPrice": 95000.0,
"takeProfitPrice": 123500.0,
"stopLossPrice": 85500.0,
"side": "long"
}
}
### Avantis Trade History
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
}'
**Request Body:**
{
"venue": "AVANTIS", // REQUIRED for Avantis via /history
"userAddress": "0x...", // REQUIRED — the trader's wallet address
"agentAddress": "0x...", // Alternative to userAddress
"count": 50 // Optional — max results (default: 50)
}
**Response:**
{
"success": true,
"venue": "AVANTIS",
"source": "avantis_api_v2_history",
"history": [
{
"id": "69a6e3b7...",
"tradeId": "1:0",
"market": "BTC/USD",
"pairIndex": 1,
"tradeIndex": 0,
"side": "long",
"collateralUsdc": 9.955,
"positionSizeUsdc": 1772.544045,
"leverage": 10.0,
"entryPrice": 67120.23805881,
"closePrice": 67014.2049318,
"usdcSentToTrader": 9.765164,
"closedAt": "2026-03-03T13:35:51.000Z",
"timestamp": 1709000000,
"grossPnlUsdc": -0.144682
}
],
"count": 4
}
### Avantis Parameter Dependency Graph
| Parameter | Source | How to Get |
|-----------|--------|-----------|
| `userAddress` | `/user-details` → `user_wallet` | `GET /user-details` |
| `agentAddress` | `/user-details` → `ostium_agent_address` | `GET /user-details` |
| `avantis_enabled` | `/user-details` → `deployment.enabled_venues` includes `AVANTIS` | `GET /user-details` |
| `market` | User specifies token | User input (e.g. `BTC`, `ETH`) |
| `side` | User specifies `"long"` or `"short"` | User input (required) |
| `collateral` | User specifies USDC amount (must satisfy venue minimums) | User input (required) |
| `leverage` | User specifies | User input |
| `tradeId` | `/avantis/positions` → `tradeId` (`<pairIndex>:<tradeIndex>`) | Preferred unique open-trade key |
| `tradeIndex` | `/avantis/positions` → `tradeIndex` | From position data |
### Avantis Workflow: Open Position on Base Chain
Step 1: GET /user-details
→ Extract: user_wallet, ostium_agent_address (shared agent wallet)
→ Check: deployment.enabled_venues includes AVANTIS (if not, tell user to enable Avantis at maxxit.ai/openclaw)
Step 2: GET /avantis/symbols
→ Verify the token is available on Avantis
Step 3: ASK the user for ALL trade parameters
→ "Which token?" (e.g. BTC, ETH)
→ "Long or short?"
→ "How much USDC collateral?"
→ "Leverage? (e.g. 10x)"
→ "Would you like to set TP/SL? If so, what percentages?"
Step 4: POST /avantis/open-position
→ Use agentAddress and userAddress from Step 1
→ Use market, side, collateral, leverage from Step 3
→ SAVE: tradeIndex and entryPrice from response
### Avantis Workflow: Close Position
Step 1: GET /user-details → Extract user_wallet, ostium_agent_address (shared agent wallet)
Step 2: POST /avantis/positions (userAddress + agentAddress)
→ Show positions to user, let them pick which to close
→ Extract tradeIndex
Step 3: POST /avantis/close-position
→ Pass agentAddress, userAddress, market
→ Optionally pass actualTradeIndex
---
## Zerodha (Indian Stocks) Endpoints
> Zerodha is an Indian stock broker supporting equities on NSE and BSE. Use Zerodha endpoints when the user wants to trade Indian stocks, mentions NSE/BSE, or says "Indian stocks", "equities", or "Zerodha".
### When to Use Zerodha
- User wants to trade Indian stocks on NSE or BSE
- User mentions "Indian stocks", "equities", "NSE", "BSE", "Zerodha", or "Kite"
- User asks about their Zerodha portfolio, holdings, or positions
- User wants to place, modify, or cancel orders on Indian exchanges
- User wants to fetch instrument lists or market data for Indian equities
### Currency Convention
- In Indian-market conversations, present prices, holdings, portfolio values, targets, and stop losses in **₹**
- Prefer `₹` in normal user-facing replies
- Do not default to USD when the context is Zerodha, NSE, BSE, or Indian equities
### TP/SL and GTT Guidance
- When the user wants to set a take profit or stop loss for a Zerodha position, confirm whether they want to place a **GTT** order.
- Explain GTT briefly when needed: **GTT (Good Till Triggered)** is a Zerodha trigger order that stays active until the trigger condition is hit or the user cancels it, and it is commonly used to automate target and stop-loss execution for cash-market positions.
- If the user explicitly asks for GTT, use the Zerodha GTT flow directly.
- If the user asks for TP/SL but does not mention GTT, ask first instead of assuming they want a regular order or a GTT trigger.
### Venue Routing
| Keywords | Route |
|----------|-------|
| "Indian stocks", "NSE", "BSE", "equities", "Zerodha", "Kite" | Zerodha endpoints |
### Environment Variables
| Variable | Description | Source |
|----------|-------------|--------|
| `KITE_API_KEY` | Zerodha Kite Connect API key | SSM (set in OpenClaw UI) |
| `KITE_API_SECRET` | Zerodha Kite Connect API secret | SSM (set in OpenClaw UI) |
| `KITE_ACCESS_TOKEN` | Short-lived access token (expires daily) | SSM (auto-stored after OAuth) |
| `KITE_USER_NAME` | Zerodha display name for status/UI | SSM (auto-stored after OAuth) |
### Auth Pre-Flight
Before any Zerodha trading call, check session validity:
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/session" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}"
If `authenticated: false` or `expired: true`, tell the user:
> "Your Zerodha session has expired. Please re-authenticate on the OpenClaw page at maxxit.ai/openclaw."
**Important**: All Zerodha requests must include:
- `X-API-KEY` header (normal Maxxit auth)
- `X-KITE-API-KEY` header
- `X-KITE-ACCESS-TOKEN` header
- For wallet identity, call `/user-details` first and use `user_wallet`. Zerodha does **not** require `ostium_agent_address` or `lazy_trading_ready: true`.
### Zerodha Endpoints
All base path: `${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/`
#### GET /zerodha/login
Generate a Zerodha login URL for the user.
Important:
- Do not tell the user to open a bare Kite URL like `https://kite.zerodha.com/connect/login?api_key=...&v=3`.
- The login flow must preserve the Maxxit user context so the callback can store the Zerodha session against the correct wallet.
- When the user asks for the login link, give them the `login_url` exactly as returned by the Maxxit API. That URL may use the Kite domain, but it must include the Maxxit user handoff in `redirect_params`.
- Preferred flow:
1. Call `GET /user-details` to resolve `user_wallet`.
2. Call `GET /zerodha/login` with `X-API-KEY`.
3. Send the returned `login_url` to the user.
- Do **not** manually construct a `?userWallet=<wallet>&redirect=1` URL in the normal skill flow.
- If you present the returned `login_url`, only use it if it includes the user handoff, e.g. `redirect_params=userWallet%3D...`.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/login" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
**Response:**
{
"success": true,
"login_url": "https://kite.zerodha.com/connect/login?api_key=5wh5hi6ky7y8s6g4&v=3&redirect_params=userWallet%3D0x796a837c78326ba693847deebd7811d6b6854c56",
"message": "Open the login_url in your browser to authenticate with Zerodha."
}
#### GET /zerodha/session
Check Zerodha session status. Returns `authenticated: true` if session is valid.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/session" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}"
#### DELETE /zerodha/session
Invalidate Zerodha session and remove token from SSM.
#### GET /zerodha/portfolio
Fetch portfolio data. Use `?type=profile|holdings|positions|margins` to select specific data. Default fetches all.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/portfolio" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}"
With filter:
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/portfolio?type=holdings" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}"
#### GET /zerodha/orders
List all orders. Use `?orderId=<id>` for specific order history.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/orders" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}"
#### POST /zerodha/orders
Place a new order.
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/orders" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}" \
-H 'Content-Type: application/json' \
-d '{
"variety": "regular",
"exchange": "NSE",
"tradingsymbol": "RELIANCE",
"transaction_type": "BUY",
"quantity": 1,
"product": "CNC",
"order_type": "MARKET"
}'
**Required fields:** `exchange`, `tradingsymbol`, `transaction_type`, `quantity`, `product`, `order_type`
**Common values:**
| Field | Values |
|-------|--------|
| `variety` | `regular`, `amo`, `co`, `iceberg`, `auction` |
| `exchange` | `NSE`, `BSE`, `NFO`, `BFO`, `CDS`, `MCX` |
| `transaction_type` | `BUY`, `SELL` |
| `product` | `CNC`, `NRML`, `MIS`, `MTF` |
| `order_type` | `MARKET`, `LIMIT`, `SL`, `SL-M` |
| `validity` | `DAY`, `IOC`, `TTL` |
**How to explain Zerodha order fields to a normal trader:**
| Field | Value | Meaning for a trader |
|-------|-------|----------------------|
| `variety` | `regular` | Standard exchange order placed during market hours. Use this by default unless the user asks for something more specific. |
| `variety` | `amo` | After Market Order. Place the order outside market hours so it gets queued for the next session. |
| `variety` | `co` | Cover Order. An intraday order paired with a compulsory stop loss. Use only if the user specifically wants a leveraged intraday order with a built-in risk stop. |
| `variety` | `iceberg` | Iceberg Order. Splits one large order into smaller legs so the full size is not sent at once. Useful for quantities above freeze limits or to reduce visible impact. |
| `variety` | `auction` | Auction Order. Used for exchange auction sessions, not for normal cash-market trading. Only use when the user explicitly wants auction participation. |
| `order_type` | `MARKET` | Buy or sell immediately at the best available price. Prioritizes execution over exact price. |
| `order_type` | `LIMIT` | Execute only at the specified price or better. Prioritizes price control over certainty of fill. |
| `order_type` | `SL` | Stop-loss limit order. Once the trigger is hit, Zerodha places a limit order. Gives price control, but the order may remain unfilled in fast moves. |
| `order_type` | `SL-M` | Stop-loss market order. Once the trigger is hit, Zerodha places a market order. Better for ensuring exit, but fill price can slip. |
| `product` | `CNC` | Cash and Carry. Standard delivery equity order for shares you want to hold, typically in NSE/BSE cash markets. |
| `product` | `NRML` | Normal order type commonly used for futures and options carry-forward positions, and other non-intraday derivatives exposure. |
| `product` | `MIS` | Margin Intraday Squareoff. Intraday-only product, typically for futures/options or same-day cash trading where the position is not meant to be carried overnight. |
| `product` | `MTF` | Margin Trading Facility. Broker-funded carry-forward equity position. Use only if the user explicitly asks for MTF and their account supports it. |
| `validity` | `DAY` | Order stays active for the current trading session unless filled or cancelled. |
| `validity` | `IOC` | Immediate or Cancel. Whatever can fill immediately will execute; the rest is cancelled right away. |
| `validity` | `TTL` | Time to Live. The order stays active only for the specified number of minutes, using `validity_ttl`. |
| `market_protection` | `0` | No market protection. Default behavior. |
| `market_protection` | `0 - 100` | Custom market-protection percentage for market and stop-market style execution. Helps cap how far execution can chase price. Example: `2` means 2%. |
| `market_protection` | `-1` | Automatic market protection chosen by the system based on Zerodha rules. |
| `autoslice` | `true` | Automatically split a large order into multiple slices when quantity is above freeze limits. |
| `autoslice` | `false` | Do not auto-slice. Default behavior. |
**Extra order parameters supported by this route:**
- `validity_ttl`: number of minutes when `validity` is `TTL`
- `iceberg_legs`: number of child legs for an iceberg order
- `iceberg_quantity`: quantity per iceberg leg
- `auction_number`: required when placing auction orders
- `market_protection`: market protection setting for eligible orders
- `autoslice`: whether Zerodha should automatically slice oversized orders
**Agent guidance:**
- Default to `variety: regular`, `validity: DAY`, and either `MARKET` or `LIMIT` based on what the user asks.
- Do not choose `CO`, `iceberg`, `auction`, `MTF`, `TTL`, `market_protection`, or `autoslice` unless the user explicitly wants that behavior or it is clearly necessary for the order they described.
- If the user asks in plain English, translate the intent into these fields and explain the tradeoff briefly before placing the order.
#### PUT /zerodha/orders?orderId=<id>
Modify an existing order.
curl -L -X PUT "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/orders?orderId=ORD123" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}" \
-H 'Content-Type: application/json' \
-d '{"variety": "regular", "price": 2500, "order_type": "LIMIT"}'
#### DELETE /zerodha/orders?orderId=<id>
Cancel an order.
curl -L -X DELETE "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/orders?orderId=ORD123" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}" \
-H 'Content-Type: application/json' \
-d '{"variety": "regular"}'
#### GET /zerodha/gtt
List all GTT triggers. Use `?triggerId=<id>` to fetch a specific trigger.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/gtt" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}"
#### POST /zerodha/gtt
Place a new GTT trigger.
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/gtt" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}" \
-H 'Content-Type: application/json' \
-d '{
"trigger_type": "two-leg",
"tradingsymbol": "SBIN",
"exchange": "NSE",
"trigger_values": [800, 840],
"last_price": 835,
"orders": [
{
"transaction_type": "SELL",
"quantity": 1,
"product": "CNC",
"order_type": "LIMIT",
"price": 840
},
{
"transaction_type": "SELL",
"quantity": 1,
"product": "CNC",
"order_type": "LIMIT",
"price": 800
}
]
}'
**Required fields:** `trigger_type`, `tradingsymbol`, `exchange`, `trigger_values`, `last_price`, `orders`
**Rules:**
- `trigger_type: "single"` requires exactly 1 `trigger_values` item and 1 order
- `trigger_type: "two-leg"` requires exactly 2 `trigger_values` items and 2 orders
#### PUT /zerodha/gtt?triggerId=<id>
Modify an existing GTT trigger.
curl -L -X PUT "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/gtt?triggerId=219118727" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}" \
-H 'Content-Type: application/json' \
-d '{
"trigger_type": "two-leg",
"tradingsymbol": "SBIN",
"exchange": "NSE",
"trigger_values": [800, 860],
"last_price": 837,
"orders": [
{
"transaction_type": "SELL",
"quantity": 1,
"product": "CNC",
"order_type": "LIMIT",
"price": 860
},
{
"transaction_type": "SELL",
"quantity": 1,
"product": "CNC",
"order_type": "LIMIT",
"price": 800
}
]
}'
#### DELETE /zerodha/gtt?triggerId=<id>
Delete an existing GTT trigger.
curl -L -X DELETE "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/gtt?triggerId=219118727" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}"
#### GET /zerodha/instruments
Fetch available instruments. Use `?exchange=NSE|BSE|NFO|BFO|CDS|MCX` to filter.
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/zerodha/instruments?exchange=NSE" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-KITE-API-KEY: ${KITE_API_KEY}" \
-H "X-KITE-ACCESS-TOKEN: ${KITE_ACCESS_TOKEN}"
### Zerodha Workflow: Trading Indian Stocks
Step 1: GET /zerodha/session
→ Check if authenticated. If not → tell user to re-auth on OpenClaw page.
Step 2: GET /user-details
→ Extract: user_wallet
→ Ignore lazy_trading_ready / ostium_agent_address for Zerodha flows
Step 3: GET /zerodha/instruments?exchange=NSE
→ Verify the symbol exists on the exchange.
Step 4: GET /zerodha/portfolio?type=holdings
→ Show current holdings and positions to user.
Step 5: ASK user for trade parameters
→ Exchange (NSE/BSE), symbol, BUY/SELL, quantity, product (CNC/MIS), order type
Step 6: POST /zerodha/orders
→ Place the order with confirmed parameters.
Step 7: GET /zerodha/orders?orderId=
→ Verify order status.
### Zerodha Error Handling
| Status | Meaning |
|--------|---------|
| 401 | Session expired. Tell user to re-authenticate. |
| 400 | Missing or invalid parameters. |
| 405 | Wrong HTTP method. |
| 500 | Internal error or Zerodha API failure. |
---
Trustless ZK-verified trading signals. **Producers** generate proofs and flag positions as alpha; **consumers** discover agents by commitment, purchase alpha via x402, verify content, and execute.
**Base path:** `${MAXXIT_API_URL}/api/lazy-trading/programmatic/alpha/*`
**Auth:** `X-API-KEY` header (same as other endpoints).
**Payment:** On-chain USDC on Arbitrum Sepolia (testnet) or Arbitrum One (mainnet).
**Prerequisites for consuming alpha:**
- User must have completed Lazy Trading setup (agent deployed) — `/user-details` must return `ostium_agent_address`. The `/pay` endpoint uses this agent to send USDC; without it, `/pay` returns 400.
- Agent wallet must hold enough USDC for the listing price. If insufficient, `/pay` returns 402 with `required` and `available` amounts — inform the user to fund the agent address.
### Alpha Endpoints Summary
| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/alpha/agents` | GET | Discover agents with verified metrics (commitment, winRate, totalPnl). Query: `minWinRate`, `minTrades`, `limit`. |
| `/alpha/listings` | GET | Browse active alpha listings (metadata + price, no trade content). Query: `commitment`, `maxPrice`, `limit`. |
| `/alpha/purchase/:listingId` | GET | **Phase 1** (no `X-Payment` header): returns 402 + payment details. **Phase 2** (with `X-Payment: txHash`): verifies on-chain, returns alpha. |
| `/alpha/pay/:listingId` | POST | **Payment helper**: sends USDC from your agent on-chain. Returns `txHash`. Call between Phase 1 and Phase 2. |
| `/alpha/verify` | POST | Body: `{ listingId, content }`. Verify purchased content hash matches commitment. |
| `/alpha/execute` | POST | Body: `{ alphaContent, agentAddress, userAddress, collateral, leverageOverride? }`. Execute alpha trade on the venue from `alphaContent.venue` (`OSTIUM` or `AVANTIS`). |
| `/alpha/generate-proof` | POST | (Producer) Generate ZK proof of trading performance. Body: `{ venue?: \"OSTIUM\" | \"AVANTIS\", tradeId?: string, autoProcess?: boolean }`. Pass `tradeId` to feature a specific trade; omit for most recent open trade. `autoProcess: false` is processed by the worker (~3-5 min). |
| `/alpha/proof-status` | GET | (Producer) Check proof processing status. Query: `proofId`. |
| `/alpha/my-proof` | GET | (Producer) Latest proof status and metrics. |
| `/alpha/flag` | POST | (Producer) Body: `{ proofId, priceUsdc, token, side, leverage? }`. List verified trade as alpha using the proof ID from generate-proof. |
**Venue/trade reference notes:**
- `tradeId` for `venue: "OSTIUM"` should be the trade index (example: `"123"`).
- For `venue: "AVANTIS"`, use tradeId from `/avantis/positions`: `"<pairIndex>:<tradeIndex>"` (example: `"1:0"`).
- Internally, proofs/listings are stored as a prefixed trade reference: `<VENUE>:<ID>` (for example, `OSTIUM:123`, `AVANTIS:1:0`).
### How x402 Purchase Works (3 API Calls)
> **⚠️ CRITICAL**: To purchase alpha content you MUST call these 3 endpoints in this exact order. Do NOT skip steps. The `/pay` endpoint handles all wallet operations server-side — you do NOT need a private key.
Step A: GET /alpha/purchase/{listingId} → 402 + paymentDetails
Step B: POST /alpha/pay/{listingId} → { txHash }
Step C: GET /alpha/purchase/{listingId} → 200 + alpha content
**Step A — Get payment details:**
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/alpha/purchase/{listingId}" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
Response: `402` with `paymentDetails.price`, `paymentDetails.payTo`, `paymentDetails.network`.
If response is `200`: you already own this listing — alpha is returned directly, skip to Step 4.
**Step B — Send USDC (server handles everything):**
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/alpha/pay/{listingId}" \
-H "X-API-KEY: ${MAXXIT_API_KEY}"
Response: `200` with `txHash`, `from`, `to`, `amount`.
If `alreadyPaid: true`: use the returned `txHash` directly.
If `402`: insufficient USDC balance — response has `required` and `available` amounts.
**Step C — Retrieve alpha content:**
curl -L -X GET "${MAXXIT_API_URL}/api/lazy-trading/programmatic/alpha/purchase/{listingId}" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "X-Payment: {txHash from Step B}"
Response: `200` with `alpha` object (token, side, leverage, venue, entryPrice), `contentHash`, `payment` receipt.
**SAVE from Step C:** `alpha`, `contentHash`, `listingId` — needed for `/verify` and `/execute`.
**Pass `content` exactly as received:** For `/alpha/verify`, the `content` field must be the exact `alpha` object from Step C. Do not modify keys, values, or key order — the hash is computed using sorted keys and any change will cause verification to fail.
### Alpha Dependency Chain
/alpha/agents → commitment
/alpha/listings → listingId (needs commitment)
/alpha/purchase → 402 paymentDetails (needs listingId)
/alpha/pay → txHash (needs listingId)
/alpha/purchase → alpha content (needs listingId + txHash in X-Payment header)
/alpha/verify → verified (needs listingId + alpha content)
/user-details → agentAddress, userAddress
/alpha/execute → trade result (needs alpha + addresses + collateral)
### Workflow: Consuming Alpha (Complete Flow)
Step 1: GET /alpha/agents
→ Pick an agent by commitment, winRate, totalPnl
→ SAVE: commitment
Step 2: GET /alpha/listings?commitment={commitment}
→ Browse listings, pick one
→ SAVE: listingId
Step 3a: GET /alpha/purchase/{listingId}
→ If 200: already purchased, skip to Step 4
→ If 402: need to pay → go to Step 3b
Step 3b: POST /alpha/pay/{listingId}
→ Server sends USDC from your agent to the producer
→ If 402: insufficient USDC balance → fund your agent wallet and retry
→ If alreadyPaid: use the returned txHash
→ SAVE: txHash
Step 3c: GET /alpha/purchase/{listingId}
→ Header: X-Payment: {txHash from Step 3b}
→ SAVE: alpha, contentHash, listingId
Step 4: POST /alpha/verify
→ Body: { "listingId": "...", "content": { ...alpha from Step 3c } }
→ Check: verified === true
Step 5: GET /user-details
→ Extract: user_wallet → userAddress
→ Extract: ostium_agent_address → agentAddress
Step 6: POST /alpha/execute
→ Body: { "alphaContent": { ...alpha }, "agentAddress": "...",
"userAddress": "...", "collateral": 100 }
→ alphaContent must include at least token and side (from alpha)
→ agentAddress = ostium_agent_address, userAddress = user_wallet (both from /user-details)
→ collateral: ask user or use default (e.g. 100 USDC)
→ Check: success === true
### Workflow: Producing Alpha
> **⚠️ This is the standalone producer workflow.** If the user just opened a position via Workflow 1, Steps 7-10 already handle alpha listing — you don't need to repeat this. Use this workflow only when the user wants to list an existing open position.
Step 1: POST /positions (address = user_wallet from /user-details)
→ List open positions
→ Let user pick which trade to feature
→ SAVE: tradeId, market (token), side, leverage from the chosen position
Step 2: POST /alpha/generate-proof
→ Body: { "venue": "OSTIUM", "tradeId": "{tradeId from Step 1}", "autoProcess": true }
→ SAVE: proofId from response
→ If status is already VERIFIED → go to Step 4
Step 3: Poll GET /alpha/proof-status?proofId={proofId}
→ Wait until status === "VERIFIED"
→ Poll every 10 seconds (max ~5 min)
→ If FAILED → inform user and stop
Step 4: ASK user for price
→ "What USDC price would you like to charge for this alpha?"
Step 5: POST /alpha/flag
→ Body: {
"proofId": "{proofId from Step 2}",
"priceUsdc": {price from Step 4},
"token": "{market from Step 1}",
"side": "{side from Step 1}",
"leverage": {leverage from Step 1}
}
→ Show user: listingId, proofMetrics (tradeCount, winRate, totalPnl)
→ "Your trade is listed as alpha! Listing ID: {listingId}"
**Example curl commands:**
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/alpha/generate-proof" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"venue":"OSTIUM","tradeId":"1612509","autoProcess":false}'
curl -G "${MAXXIT_API_URL}/api/lazy-trading/programmatic/alpha/proof-status" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
--data-urlencode "proofId=
curl -L -X POST "${MAXXIT_API_URL}/api/lazy-trading/programmatic/alpha/flag" \
-H "X-API-KEY: ${MAXXIT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"proofId": "
---
## Environment Variables
| Variable | Description | Example |
|----------|-------------|---------|
| `MAXXIT_API_KEY` | Your lazy trading API key (starts with `lt_`) | `lt_abc123...` |
| `MAXXIT_API_URL` | Maxxit API base URL | `https://maxxit.ai` |
## Error Handling
| Status Code | Meaning |
|-------------|---------|
| 401 | Invalid or missing API key |
| 404 | Resource not found for the specific endpoint (not returned by `/user-details` just because an agent is missing) |
| 400 | Missing or invalid message / parameters |
| 405 | Wrong HTTP method |
| 500 | Server error |
**Alpha-specific errors:**
| 400 | `/pay`: No agent address found (user must complete Lazy Trading setup). `/purchase`: Invalid X-Payment header or payment verification failed. |
| 402 | Payment required (`/purchase` Phase 1) or insufficient USDC balance (`/pay` — check `required` and `available` in response). |
| 409 | Transaction hash already used (replay protection — each tx can only purchase one listing). |
| 410 | Alpha listing no longer active. |
## Getting Started
1. **Set up Lazy Trading**: Visit https://maxxit.ai/lazy-trading to connect your wallet and configure your agent
2. **Generate API Key**: Go to your dashboard and create an API key
3. **Configure Environment**: Set `MAXXIT_API_KEY` and `MAXXIT_API_URL`
4. **Start Trading**: Use this skill to send signals!
## Security Notes
- Never share your API key
- API keys can be revoked and regenerated from the dashboard
- All trades execute on-chain with your delegated wallet permissions
共 6 个版本