
Copy Trading
- 16 installs
- 610 repo stars
- Updated June 26, 2026
- alsk1992/cloddsbot
Copy Trading is a skill that automatically mirrors trades from successful wallets on Polymarket and crypto with configurable sizing, delay and risk limits.
About
Copy Trading is a skill that mirrors trades from other wallets on Polymarket and crypto chains. A developer follows a wallet, sets sizing and delay, applies risk limits, and lets the service auto-exit on stop-loss or take-profit. It matters for building an agent that follows profitable traders with configurable risk.
- Automatically mirror trades from successful wallets on Polymarket and crypto
- Fixed, proportional or portfolio-percentage position sizing
- Risk controls with max position, daily loss limits and auto stop-loss/take-profit
Copy Trading by the numbers
- 16 all-time installs (skills.sh)
- Ranked #739 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
copy-trading capabilities & compatibility
- Capabilities
- copy trading solana · crypto hft · divergence
- Use cases
- trading
- Pricing
- Bring your own API key
What copy-trading says it does
Automatically mirror trades from successful wallets with configurable sizing, delays, and risk controls.
npx skills add https://github.com/alsk1992/cloddsbot --skill copy-tradingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 16 |
|---|---|
| repo stars | ★ 610 |
| Last updated | June 26, 2026 |
| Repository | alsk1992/cloddsbot ↗ |
What it does
Follow and mirror trades from successful wallets on Polymarket and crypto with sizing, delay and risk limits.
Who is it for?
Copying whale wallets on Polymarket and crypto with risk controls
When should I use this skill?
You want to auto-mirror another wallet's trades with your own sizing rules
By the numbers
- 3 sizing modes: fixed, proportional, portfolio
Files
Copy Trading - Complete API Reference
Automatically mirror trades from successful wallets with configurable sizing, delays, and risk controls.
Features
- Follow whale wallets on Polymarket and crypto chains
- Configurable sizing: Fixed, proportional, or % of portfolio
- Trade delay to avoid detection and front-running
- Risk limits: Max position, daily loss limits
- Stop-loss / Take-profit monitoring with auto-exit
---
Chat Commands
Following Wallets
/copy follow <address> # Start following a wallet
/copy follow 0x1234... --size 100 # Follow with $100 fixed size
/copy follow 0x1234... --size 50% # Follow with 50% of their size
/copy follow 0x1234... --delay 30 # 30 second delay before copying
/copy unfollow <address> # Stop following
/copy list # List followed wallets
/copy status # Show copy trading statusSizing Modes
/copy size <address> fixed 100 # Always trade $100
/copy size <address> proportional 0.5 # 50% of their size
/copy size <address> portfolio 5% # 5% of your portfolioRisk Controls
/copy limits --max-position 1000 # Max $1000 per position
/copy limits --daily-loss 500 # Stop after $500 daily loss
/copy limits --max-trades 20 # Max 20 trades per day
/copy sl <address> 10% # 10% stop-loss on copies
/copy tp <address> 20% # 20% take-profit on copiesDiscovery
/copy top 10 # Top 10 traders to copy
/copy top 10 --min-winrate 60 # Min 60% win rate
/copy top 10 --min-volume 100000 # Min $100k volume
/copy analyze <address> # Analyze a trader's performance---
TypeScript API Reference
Create Copy Trading Service
import { createCopyTradingService } from 'clodds/trading/copy-trading';
const copyTrader = createCopyTradingService({
// Polymarket credentials
polymarket: {
apiKey: process.env.POLY_API_KEY,
apiSecret: process.env.POLY_API_SECRET,
passphrase: process.env.POLY_API_PASSPHRASE,
privateKey: process.env.PRIVATE_KEY,
},
// Default settings
defaults: {
sizingMode: 'proportional',
sizingValue: 0.5, // 50% of their size
delaySeconds: 15, // 15s delay
maxPositionSize: 1000, // $1000 max
stopLossPct: 10, // 10% stop-loss
takeProfitPct: 25, // 25% take-profit
},
// Risk limits
limits: {
maxDailyLoss: 500,
maxDailyTrades: 20,
maxTotalExposure: 5000,
},
});Follow Wallets
// Follow a wallet with default settings
await copyTrader.follow('0x1234...');
// Follow with custom settings
await copyTrader.follow('0x1234...', {
sizingMode: 'fixed',
sizingValue: 100, // $100 per trade
delaySeconds: 30, // 30s delay
stopLossPct: 15, // 15% stop-loss
takeProfitPct: 30, // 30% take-profit
// Filters
minTradeSize: 50, // Only copy trades > $50
maxTradeSize: 5000, // Skip trades > $5000
markets: ['politics'], // Only copy politics markets
});
// Unfollow
await copyTrader.unfollow('0x1234...');
// List followed
const followed = await copyTrader.listFollowed();Sizing Modes
// Fixed: Always trade same dollar amount
await copyTrader.follow(address, {
sizingMode: 'fixed',
sizingValue: 100, // Always $100
});
// Proportional: Percentage of their trade size
await copyTrader.follow(address, {
sizingMode: 'proportional',
sizingValue: 0.5, // 50% of their size
});
// Portfolio: Percentage of your portfolio
await copyTrader.follow(address, {
sizingMode: 'portfolio',
sizingValue: 0.05, // 5% of portfolio per trade
});Event Handling
copyTrader.on('trade_copied', (event) => {
console.log(`Copied ${event.side} on ${event.market}`);
console.log(`Original: $${event.originalSize}, Copied: $${event.copiedSize}`);
});
copyTrader.on('stop_loss_triggered', (event) => {
console.log(`Stop-loss hit on ${event.market}`);
console.log(`Loss: $${event.loss}`);
});
copyTrader.on('take_profit_triggered', (event) => {
console.log(`Take-profit hit on ${event.market}`);
console.log(`Profit: $${event.profit}`);
});
copyTrader.on('limit_reached', (event) => {
console.log(`Limit reached: ${event.type}`);
});Start/Stop
// Start copy trading (monitors followed wallets)
await copyTrader.start();
// Stop copy trading
await copyTrader.stop();
// Get status
const status = copyTrader.getStatus();
console.log(`Following: ${status.followedCount} wallets`);
console.log(`Today's P&L: $${status.dailyPnl}`);
console.log(`Active positions: ${status.activePositions}`);Find Best Traders
import { findBestAddressesToCopy } from 'clodds/trading/copy-trading';
// Find top traders
const topTraders = await findBestAddressesToCopy({
minWinRate: 0.6, // 60%+ win rate
minVolume: 100000, // $100k+ volume
minTrades: 50, // 50+ trades
timeframeDays: 30, // Last 30 days
limit: 10, // Top 10
});
for (const trader of topTraders) {
console.log(`${trader.address}`);
console.log(` Win rate: ${(trader.winRate * 100).toFixed(1)}%`);
console.log(` Volume: $${trader.totalVolume.toLocaleString()}`);
console.log(` P&L: $${trader.pnl.toLocaleString()}`);
console.log(` Trades: ${trader.tradeCount}`);
}Analyze Trader
const analysis = await copyTrader.analyzeTrader('0x1234...');
console.log(`Win rate: ${analysis.winRate}%`);
console.log(`Avg trade size: $${analysis.avgTradeSize}`);
console.log(`Best market: ${analysis.bestMarket}`);
console.log(`Worst market: ${analysis.worstMarket}`);
console.log(`Avg hold time: ${analysis.avgHoldTime} hours`);
console.log(`Sharpe ratio: ${analysis.sharpeRatio}`);---
Risk Management
Stop-Loss Monitoring
Copy trading includes automatic stop-loss monitoring with 5-second price polling:
// Configure stop-loss per followed wallet
await copyTrader.follow(address, {
stopLossPct: 10, // Exit at 10% loss
});
// Or set global stop-loss
copyTrader.setGlobalStopLoss(15); // 15% for all positionsTake-Profit Monitoring
// Configure take-profit per followed wallet
await copyTrader.follow(address, {
takeProfitPct: 25, // Exit at 25% profit
});
// Trailing take-profit
await copyTrader.follow(address, {
trailingTakeProfit: true,
trailingPct: 5, // Trail by 5%
});Daily Limits
const copyTrader = createCopyTradingService({
limits: {
maxDailyLoss: 500, // Stop after $500 loss
maxDailyTrades: 20, // Max 20 trades
maxTotalExposure: 5000, // Max $5k total exposure
},
});---
Best Practices
1. Start with small sizes - Test with 10-25% proportional sizing 2. Use delays - 15-30 second delays reduce front-running risk 3. Set stop-losses - Always use 10-15% stop-loss 4. Diversify - Follow 3-5 wallets, not just one 5. Monitor regularly - Check performance daily 6. Filter markets - Focus on categories you understand
/**
* Copy Trading CLI Skill
*
* Commands:
* /copy follow <address> - Start following a wallet
* /copy unfollow <address> - Stop following
* /copy list - List followed wallets
* /copy status - Copy trading status
* /copy trades - Recent copied trades
* /copy close <id> - Close a copied position
* /copy config - View/update config
*/
// Module-level singleton so state persists across commands
let serviceInstance: any = null;
async function getService() {
if (!serviceInstance) {
const { createCopyTradingService } = await import('../../../trading/copy-trading');
const { createWhaleTracker } = await import('../../../feeds/polymarket/whale-tracker');
const tracker = createWhaleTracker();
const config = {
followedAddresses: [],
dryRun: true,
};
serviceInstance = createCopyTradingService(tracker, null, config);
}
return serviceInstance;
}
async function execute(args: string): Promise<string> {
const parts = args.trim().split(/\s+/);
const cmd = parts[0]?.toLowerCase() || 'help';
try {
const service = await getService();
switch (cmd) {
case 'follow': {
if (!parts[1]) return 'Usage: /copy follow <address> [--size <amount>] [--delay <ms>]';
const addr = parts[1];
const sizeIdx = parts.indexOf('--size');
const size = sizeIdx >= 0 ? parts[sizeIdx + 1] : '100';
const delayIdx = parts.indexOf('--delay');
const delay = delayIdx >= 0 ? parts[delayIdx + 1] : '5000';
// follow() only accepts address; apply size/delay via updateConfig
service.follow(addr);
const configUpdates: Record<string, unknown> = {};
if (sizeIdx >= 0) {
const parsedSize = parseFloat(size);
if (isNaN(parsedSize)) return 'Size must be a number. Usage: /copy follow <address> [--size <amount>]';
configUpdates.fixedSize = parsedSize;
}
if (delayIdx >= 0) {
const parsedDelay = parseInt(delay, 10);
if (isNaN(parsedDelay)) return 'Delay must be a number. Usage: /copy follow <address> [--delay <ms>]';
configUpdates.copyDelayMs = parsedDelay;
}
if (Object.keys(configUpdates).length > 0) service.updateConfig(configUpdates);
return `**Following Wallet**\n\nAddress: \`${addr}\`\nSize: $${size}\nDelay: ${delay}ms\nStatus: Active\nMode: Dry run (use /copy config set dryRun false to go live)`;
}
case 'unfollow': {
if (!parts[1]) return 'Usage: /copy unfollow <address>';
service.unfollow(parts[1]);
return `Unfollowed \`${parts[1]}\`.`;
}
case 'list':
case 'ls': {
const addrs = service.getFollowedAddresses();
if (!addrs.length) return 'No wallets being followed. Use `/copy follow <address>` to start.';
let output = `**Followed Wallets** (${addrs.length})\n\n`;
for (const addr of addrs) {
output += ` \`${addr}\`\n`;
}
return output;
}
case 'status': {
const stats = service.getStats();
let output = '**Copy Trading Status**\n\n';
output += `Active: ${service.isRunning() ? 'Yes' : 'No'}\n`;
output += `Following: ${stats.followedAddresses} wallets\n`;
output += `Total copied: ${stats.totalCopied} trades\n`;
output += `Total skipped: ${stats.totalSkipped}\n`;
output += `Open positions: ${stats.openPositions}\n`;
output += `Win rate: ${stats.winRate.toFixed(1)}%\n`;
output += `Total P&L: $${stats.totalPnl.toFixed(2)}\n`;
output += `Avg return: ${stats.avgReturn.toFixed(2)}%\n`;
return output;
}
case 'trades': {
const parsedLimit = parseInt(parts[1] || '10', 10);
const limit = isNaN(parsedLimit) ? 10 : parsedLimit;
const trades = service.getCopiedTrades(limit);
if (!trades.length) return 'No copied trades yet.';
let output = `**Recent Copied Trades** (last ${trades.length})\n\n`;
for (const t of trades) {
output += `[${t.status}] ${t.side} $${t.size.toFixed(2)} @ ${t.entryPrice.toFixed(4)}`;
if (t.pnl !== undefined) output += ` | P&L: $${t.pnl.toFixed(2)}`;
output += `\n From: \`${t.originalTrade.maker.slice(0, 10)}...\`\n`;
}
return output;
}
case 'positions':
case 'open': {
const positions = service.getOpenPositions();
if (!positions.length) return 'No open copied positions.';
let output = `**Open Copied Positions** (${positions.length})\n\n`;
for (const p of positions) {
output += `[${p.id}] ${p.side} $${p.size.toFixed(2)} @ ${p.entryPrice.toFixed(4)}\n`;
output += ` Status: ${p.status}\n`;
}
return output;
}
case 'close': {
if (!parts[1]) return 'Usage: /copy close <trade-id> or /copy close all';
if (parts[1] === 'all') {
await service.closeAllPositions();
return 'All copied positions closed.';
}
await service.closePosition(parts[1]);
return `Position \`${parts[1]}\` closed.`;
}
case 'start': {
service.start();
return 'Copy trading started. Monitoring followed wallets for new trades.';
}
case 'stop': {
service.stop();
return 'Copy trading stopped.';
}
case 'config': {
const sub = parts[1]?.toLowerCase();
if (sub === 'set') {
const key = parts[2];
const value = parts[3];
if (!key || !value) return 'Usage: /copy config set <key> <value>';
const updates: Record<string, unknown> = {};
if (key === 'dryRun') updates.dryRun = value === 'true';
else if (key === 'fixedSize') updates.fixedSize = parseFloat(value);
else if (key === 'maxPosition') updates.maxPositionSize = parseFloat(value);
else if (key === 'minTradeSize') updates.minTradeSize = parseFloat(value);
else if (key === 'copyDelay') updates.copyDelayMs = parseInt(value, 10);
else if (key === 'stopLoss') updates.stopLoss = parseFloat(value);
else if (key === 'takeProfit') updates.takeProfit = parseFloat(value);
else return `Unknown config key: ${key}`;
service.updateConfig(updates);
return `Config updated: ${key} = ${value}`;
}
return `**Copy Trading Config**\n\n` +
`Sizing: fixed ($100)\n` +
`Max position: $500\n` +
`Min trade size: $1,000\n` +
`Copy delay: 5,000ms\n` +
`Max slippage: 2%\n` +
`Dry run: true\n\n` +
`Use \`/copy config set <key> <value>\` to change.\n` +
`Keys: dryRun, fixedSize, maxPosition, minTradeSize, copyDelay, stopLoss, takeProfit`;
}
default:
return helpText();
}
} catch (error) {
return `Error: ${error instanceof Error ? error.message : String(error)}`;
}
}
function helpText(): string {
return `**Copy Trading Commands**
/copy follow <address> - Follow a wallet
/copy unfollow <address> - Stop following
/copy list - List followed wallets
/copy status - Current stats
/copy trades [n] - Recent copied trades
/copy positions - Open positions
/copy close <id|all> - Close position(s)
/copy start - Start copy trading
/copy stop - Stop copy trading
/copy config - View config
/copy config set <key> <value> - Update config`;
}
export default {
name: 'copy-trading',
description: 'Automatically copy trades from successful wallets on Polymarket and crypto',
commands: ['/copy', '/copytrade'],
handle: execute,
};