Skip to main content
GET
https://api-mainnet.onzks.com
/
v1
/
trading
/
stats
/
:identity
Get Trading Stats
curl --request GET \
  --url https://api-mainnet.onzks.com/v1/trading/stats/:identity \
  --header 'Authorization: Bearer <token>'
{
  "success": true,
  "address": "<string>",
  "zksId": "<string>",
  "zksTradingStats": {
    "overview": {
      "totalVolume": "<string>",
      "totalTrades": 123,
      "uniqueProtocols": 123,
      "uniqueAssets": 123,
      "activeDays": 123,
      "firstTrade": "<string>",
      "lastTrade": "<string>"
    },
    "profitability": {
      "totalPnL": "<string>",
      "realizedPnL": "<string>",
      "unrealizedPnL": "<string>",
      "winRate": 123,
      "averageWin": "<string>",
      "averageLoss": "<string>",
      "profitFactor": 123
    },
    "volume": {
      "dailyAverage": "<string>",
      "weeklyAverage": "<string>",
      "monthlyAverage": "<string>",
      "largestTrade": "<string>",
      "tradesPerDay": 123,
      "volumeGrowth": 123
    },
    "risk": {
      "maxDrawdown": "<string>",
      "maxDrawdownPercentage": 123,
      "volatility": 123,
      "riskScore": 123,
      "consecutiveLosses": 123,
      "consecutiveWins": 123
    },
    "protocols": [
      {
        "name": "<string>",
        "volume": "<string>",
        "trades": 123,
        "pnl": "<string>",
        "percentage": 123
      }
    ],
    "assets": [
      {
        "symbol": "<string>",
        "name": "<string>",
        "volume": "<string>",
        "trades": 123,
        "pnl": "<string>",
        "percentage": 123
      }
    ],
    "timeDistribution": {
      "byHour": [
        {}
      ],
      "byDay": [
        {}
      ],
      "byMonth": [
        {}
      ]
    }
  },
  "timestamp": "<string>"
}

Overview

Retrieve detailed trading statistics and performance metrics for a specific user. This endpoint provides insights into trading volume, profitability, frequency, and protocol usage, making it perfect for building trading dashboards and analytics.
Use this endpoint to display user trading performance, calculate risk scores, and provide insights into trading behavior patterns.

Parameters

identity
string
required
User identity (ZKS ID or wallet address)
ZKS ID is recommended for better performance and user experience
timeframe
string
Time period for statistics
  • 7d - Last 7 days
  • 30d - Last 30 days (default)
  • 90d - Last 90 days
  • 1y - Last year
  • all - All time
chainId
number
Filter by specific blockchain
  • 1 - Ethereum mainnet
  • 137 - Polygon
  • 56 - BSC
  • 42161 - Arbitrum
  • 10 - Optimism
  • 250 - Fantom
  • 43114 - Avalanche
includeBreakdown
boolean
Include detailed breakdown by protocol and asset (default: true)

Response

success
boolean
Indicates if the request was successful
address
string
Resolved wallet address
zksId
string
ZKS ID if available, null otherwise
zksTradingStats
object
Comprehensive trading statistics
timestamp
string
ISO 8601 timestamp of the response

Examples

curl "https://api.onzks.com/v1/trading/stats/alice.zks" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response Example

{
  "success": true,
  "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
  "zksId": "alice.zks",
  "zksTradingStats": {
    "overview": {
      "totalVolume": "1250000.50",
      "totalTrades": 342,
      "uniqueProtocols": 15,
      "uniqueAssets": 28,
      "activeDays": 45,
      "firstTrade": "2023-06-15T10:30:00Z",
      "lastTrade": "2024-01-20T15:45:00Z"
    },
    "profitability": {
      "totalPnL": "125000.75",
      "realizedPnL": "98000.25",
      "unrealizedPnL": "27000.50",
      "winRate": 68.5,
      "averageWin": "2500.00",
      "averageLoss": "-1200.00",
      "profitFactor": 2.1
    },
    "volume": {
      "dailyAverage": "27777.78",
      "weeklyAverage": "194444.44",
      "monthlyAverage": "833333.33",
      "largestTrade": "50000.00",
      "tradesPerDay": 7.6,
      "volumeGrowth": 15.2
    },
    "risk": {
      "maxDrawdown": "-15000.00",
      "maxDrawdownPercentage": 12.0,
      "volatility": 35.5,
      "riskScore": 42.3,
      "consecutiveLosses": 4,
      "consecutiveWins": 8
    },
    "protocols": [
      {
        "name": "Uniswap V3",
        "volume": "450000.00",
        "trades": 125,
        "pnl": "45000.00",
        "percentage": 36.0
      },
      {
        "name": "1inch",
        "volume": "300000.00",
        "trades": 89,
        "pnl": "25000.00",
        "percentage": 24.0
      },
      {
        "name": "SushiSwap",
        "volume": "200000.00",
        "trades": 67,
        "pnl": "18000.00",
        "percentage": 16.0
      }
    ],
    "assets": [
      {
        "symbol": "ETH",
        "name": "Ethereum",
        "volume": "500000.00",
        "trades": 150,
        "pnl": "50000.00",
        "percentage": 40.0
      },
      {
        "symbol": "USDC",
        "name": "USD Coin",
        "volume": "300000.00",
        "trades": 100,
        "pnl": "25000.00",
        "percentage": 24.0
      },
      {
        "symbol": "WBTC",
        "name": "Wrapped Bitcoin",
        "volume": "200000.00",
        "trades": 50,
        "pnl": "20000.00",
        "percentage": 16.0
      }
    ],
    "timeDistribution": {
      "byHour": [
        {"hour": 0, "trades": 5, "volume": "10000.00"},
        {"hour": 1, "trades": 3, "volume": "5000.00"},
        {"hour": 9, "trades": 25, "volume": "50000.00"},
        {"hour": 14, "trades": 30, "volume": "60000.00"},
        {"hour": 21, "trades": 20, "volume": "40000.00"}
      ],
      "byDay": [
        {"day": "Monday", "trades": 50, "volume": "100000.00"},
        {"day": "Tuesday", "trades": 45, "volume": "90000.00"},
        {"day": "Wednesday", "trades": 55, "volume": "110000.00"},
        {"day": "Thursday", "trades": 48, "volume": "95000.00"},
        {"day": "Friday", "trades": 52, "volume": "105000.00"},
        {"day": "Saturday", "trades": 35, "volume": "70000.00"},
        {"day": "Sunday", "trades": 30, "volume": "60000.00"}
      ],
      "byMonth": [
        {"month": "2023-06", "trades": 25, "volume": "50000.00"},
        {"month": "2023-07", "trades": 30, "volume": "60000.00"},
        {"month": "2023-08", "trades": 35, "volume": "70000.00"},
        {"month": "2023-09", "trades": 40, "volume": "80000.00"},
        {"month": "2023-10", "trades": 45, "volume": "90000.00"},
        {"month": "2023-11", "trades": 50, "volume": "100000.00"},
        {"month": "2023-12", "trades": 55, "volume": "110000.00"},
        {"month": "2024-01", "trades": 60, "volume": "120000.00"}
      ]
    }
  },
  "timestamp": "2024-01-20T15:45:00Z"
}

Use Cases

1. Trading Dashboard

Create a comprehensive trading dashboard:
function createTradingDashboard(stats) {
  const { overview, profitability, volume, risk } = stats.zksTradingStats;
  
  return {
    summary: {
      totalVolume: `$${parseFloat(overview.totalVolume).toLocaleString()}`,
      totalTrades: overview.totalTrades,
      winRate: `${profitability.winRate}%`,
      totalPnL: `$${parseFloat(profitability.totalPnL).toLocaleString()}`,
      riskScore: risk.riskScore
    },
    performance: {
      profitFactor: profitability.profitFactor,
      averageWin: `$${parseFloat(profitability.averageWin).toLocaleString()}`,
      averageLoss: `$${parseFloat(profitability.averageLoss).toLocaleString()}`,
      maxDrawdown: `$${parseFloat(risk.maxDrawdown).toLocaleString()}`
    },
    activity: {
      dailyAverage: `$${parseFloat(volume.dailyAverage).toLocaleString()}`,
      tradesPerDay: volume.tradesPerDay,
      activeDays: overview.activeDays,
      uniqueProtocols: overview.uniqueProtocols
    }
  };
}

2. Risk Assessment

Analyze trading risk:
function assessTradingRisk(stats) {
  const { risk, profitability } = stats.zksTradingStats;
  
  const riskLevel = risk.riskScore < 30 ? 'Low' :
                   risk.riskScore < 60 ? 'Medium' : 'High';
  
  const riskFactors = [];
  
  if (risk.maxDrawdownPercentage > 20) {
    riskFactors.push('High maximum drawdown');
  }
  
  if (risk.consecutiveLosses > 5) {
    riskFactors.push('Long losing streaks');
  }
  
  if (profitability.winRate < 50) {
    riskFactors.push('Low win rate');
  }
  
  if (risk.volatility > 70) {
    riskFactors.push('High volatility');
  }
  
  return {
    riskLevel,
    riskScore: risk.riskScore,
    riskFactors,
    recommendations: generateRiskRecommendations(risk, profitability)
  };
}

function generateRiskRecommendations(risk, profitability) {
  const recommendations = [];
  
  if (risk.maxDrawdownPercentage > 15) {
    recommendations.push('Consider reducing position sizes');
  }
  
  if (profitability.winRate < 60) {
    recommendations.push('Focus on improving trade selection');
  }
  
  if (risk.consecutiveLosses > 3) {
    recommendations.push('Implement stop-loss strategies');
  }
  
  return recommendations;
}

3. Protocol Analysis

Analyze trading by protocol:
function analyzeProtocols(stats) {
  const protocols = stats.zksTradingStats.protocols;
  
  const analysis = {
    topProtocol: protocols[0],
    totalProtocols: protocols.length,
    diversification: calculateDiversification(protocols),
    protocolPerformance: protocols.map(p => ({
      name: p.name,
      efficiency: parseFloat(p.pnl) / parseFloat(p.volume) * 100,
      volume: parseFloat(p.volume),
      trades: p.trades
    }))
  };
  
  return analysis;
}

function calculateDiversification(protocols) {
  const totalVolume = protocols.reduce((sum, p) => sum + parseFloat(p.volume), 0);
  const top3Volume = protocols.slice(0, 3).reduce((sum, p) => sum + parseFloat(p.volume), 0);
  
  return (top3Volume / totalVolume * 100).toFixed(1);
}

4. Time-based Analysis

Analyze trading patterns over time:
function analyzeTradingPatterns(stats) {
  const { timeDistribution } = stats.zksTradingStats;
  
  const patterns = {
    peakHours: findPeakHours(timeDistribution.byHour),
    peakDays: findPeakDays(timeDistribution.byDay),
    monthlyTrend: analyzeMonthlyTrend(timeDistribution.byMonth),
    consistency: calculateConsistency(timeDistribution)
  };
  
  return patterns;
}

function findPeakHours(hourlyData) {
  return hourlyData
    .sort((a, b) => b.trades - a.trades)
    .slice(0, 3)
    .map(h => ({ hour: h.hour, trades: h.trades }));
}

function findPeakDays(dailyData) {
  return dailyData
    .sort((a, b) => b.trades - a.trades)
    .slice(0, 3)
    .map(d => ({ day: d.day, trades: d.trades }));
}

5. Performance Comparison

Compare with market benchmarks:
function compareWithBenchmarks(stats) {
  const { profitability, volume } = stats.zksTradingStats;
  
  const benchmarks = {
    averageWinRate: 55, // Market average
    averageProfitFactor: 1.5,
    averageVolatility: 50
  };
  
  const comparison = {
    winRate: {
      value: profitability.winRate,
      benchmark: benchmarks.averageWinRate,
      performance: profitability.winRate > benchmarks.averageWinRate ? 'Above' : 'Below'
    },
    profitFactor: {
      value: profitability.profitFactor,
      benchmark: benchmarks.averageProfitFactor,
      performance: profitability.profitFactor > benchmarks.averageProfitFactor ? 'Above' : 'Below'
    },
    overall: calculateOverallPerformance(profitability, benchmarks)
  };
  
  return comparison;
}

Best Practices

1. Cache Trading Stats

Trading stats can be cached for short periods:
let tradingStatsCache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

async function getCachedTradingStats(identity, options = {}) {
  const cacheKey = `${identity}-${JSON.stringify(options)}`;
  const cached = tradingStatsCache.get(cacheKey);
  
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }
  
  const data = await getTradingStats(identity, options);
  tradingStatsCache.set(cacheKey, {
    data,
    timestamp: Date.now()
  });
  
  return data;
}

2. Real-time Updates

Subscribe to trading updates:
function subscribeToTradingUpdates(identity, callback) {
  const ws = new WebSocket(`wss://api.onzks.com/v1/trading/stats/${identity}/subscribe`);
  
  ws.onmessage = (event) => {
    const update = JSON.parse(event.data);
    callback(update);
  };
  
  return () => ws.close();
}

3. Batch Analysis

Analyze multiple users:
async function analyzeMultipleTraders(identities) {
  const promises = identities.map(id => getTradingStats(id));
  const results = await Promise.all(promises);
  
  return results.map((stats, index) => ({
    identity: identities[index],
    stats: stats.zksTradingStats,
    risk: assessTradingRisk(stats),
    performance: compareWithBenchmarks(stats)
  }));
}

4. Historical Comparison

Compare different time periods:
async function compareTimePeriods(identity) {
  const [current, previous] = await Promise.all([
    getTradingStats(identity, { timeframe: '30d' }),
    getTradingStats(identity, { timeframe: '60d' })
  ]);
  
  return {
    current: current.zksTradingStats,
    previous: previous.zksTradingStats,
    changes: calculateChanges(current.zksTradingStats, previous.zksTradingStats)
  };
}

Troubleshooting

”No trading data found”

Cause: User has no trading activity or invalid timeframe. Solution:
  • Check if the user has any trading activity
  • Try a longer timeframe
  • Verify the identity is correct

”Invalid timeframe”

Cause: Unsupported timeframe value. Solution:
  • Use supported timeframes: 7d, 30d, 90d, 1y, all
  • Check for typos

”Chain not supported”

Cause: Unsupported chain ID. Solution:
  • Use supported chain IDs: 1, 137, 56, 42161, 10, 250, 43114
  • Check chain ID format

Rate Limits

Trading stats requests are subject to rate limits:
  • Free tier: 60 requests per minute
  • Starter tier: 300 requests per minute
  • Professional tier: 1,000 requests per minute
  • Enterprise tier: Custom limits
Implement caching to reduce API calls.