
Trading System
- 40 installs
- 610 repo stars
- Updated June 26, 2026
- alsk1992/cloddsbot
trading-system is a skill that runs and tracks trading bots with SQLite auto-logging and performance analytics.
About
This skill is a unified trading layer that auto-logs trades to SQLite, manages trading bots, and reports performance analytics. It aggregates portfolio and positions across platforms, computes statistics like win rate, profit factor, and Sharpe ratio, and registers bots running built-in strategies such as mean-reversion, momentum, and arbitrage. A developer uses it to run and track automated trading across the clodds bot's connected platforms.
- Unified trading system with auto-logging to SQLite
- Bot management with mean-reversion, momentum, and arbitrage strategies
- Portfolio view, P&L breakdowns, and performance analytics
Trading System by the numbers
- 40 all-time installs (skills.sh)
- Ranked #636 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
trading-system capabilities & compatibility
Requires a platform API key (Polymarket or Kalshi); logs to a local SQLite file.
- Capabilities
- bot management · portfolio tracking · pnl analytics · trade logging
- Use cases
- trading · orchestration
- Runs
- Runs locally
- Pricing
- Bring your own API key
What trading-system says it does
Unified trading system with auto-logging to SQLite, bot management, and performance analytics.
Register a bot
npx skills add https://github.com/alsk1992/cloddsbot --skill trading-systemAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 40 |
|---|---|
| repo stars | ★ 610 |
| Last updated | June 26, 2026 |
| Repository | alsk1992/cloddsbot ↗ |
What it does
Run and track trading bots with auto-logging, portfolio, and P&L analytics.
Who is it for?
Orchestrating strategy bots and tracking portfolio, P&L, and stats across trading platforms.
Skip if: Executing a single manual swap on one DEX.
When should I use this skill?
You need to register/start trading bots or read portfolio, P&L, and performance stats.
What you get
Managed strategy bots with logged trades and computed performance metrics.
- Managed trading bots
- Portfolio, P&L, and statistics reports
By the numbers
- 3 built-in strategies (mean-reversion, momentum, arbitrage)
- Default maxConcurrent 5 bots
Files
Trading System - Complete API Reference
Unified trading system with auto-logging to SQLite, bot management, and performance analytics.
---
Chat Commands
Portfolio
/trading portfolio # View all positions
/trading portfolio poly # Positions on Polymarket
/trading portfolio --value # Include current valuesPerformance
/trading stats # Overall statistics
/trading stats --period 30d # Last 30 days
/trading daily-pnl # Daily P&L breakdown
/trading weekly-pnl # Weekly P&L
/trading monthly-pnl # Monthly P<rade History
/trading history # Recent trades
/trading history --limit 50 # Last 50 trades
/trading history --platform poly # Polymarket only
/trading export # Export to CSV
/trading export --format json # Export as JSONBot Management
/bot list # List all bots
/bot register <name> <strategy> # Register new bot
/bot start <name> # Start bot
/bot stop <name> # Stop bot
/bot status <name> # Bot status
/bot delete <name> # Delete botBot Strategies
/bot strategies # List available strategies
/bot create mean-reversion --config {...} # Create with config
/bot create momentum --lookback 14 # Momentum strategy
/bot create arbitrage --min-spread 1 # Arbitrage strategy---
TypeScript API Reference
Create Trading System
import { createTradingSystem } from 'clodds/trading';
const trading = createTradingSystem({
// Execution service
execution: executionService,
// Auto-logging
autoLog: true,
logPath: './trades.db',
// Bot configuration
bots: {
enabled: true,
maxConcurrent: 5,
},
});Portfolio
// Get portfolio
const portfolio = await trading.getPortfolio();
console.log(`Total value: $${portfolio.totalValue.toLocaleString()}`);
console.log(`Unrealized P&L: $${portfolio.unrealizedPnl.toLocaleString()}`);
for (const position of portfolio.positions) {
console.log(`[${position.platform}] ${position.market}`);
console.log(` Side: ${position.side}`);
console.log(` Size: ${position.size}`);
console.log(` Avg price: ${position.avgPrice}`);
console.log(` Current: ${position.currentPrice}`);
console.log(` P&L: $${position.unrealizedPnl.toFixed(2)}`);
}Statistics
// Get trading statistics
const stats = await trading.getStats({ period: '30d' });
console.log(`Total trades: ${stats.totalTrades}`);
console.log(`Win rate: ${(stats.winRate * 100).toFixed(1)}%`);
console.log(`Profit factor: ${stats.profitFactor.toFixed(2)}`);
console.log(`Total P&L: $${stats.totalPnl.toLocaleString()}`);
console.log(`Avg trade: $${stats.avgTrade.toFixed(2)}`);
console.log(`Largest win: $${stats.largestWin.toFixed(2)}`);
console.log(`Largest loss: $${stats.largestLoss.toFixed(2)}`);
console.log(`Sharpe ratio: ${stats.sharpeRatio.toFixed(2)}`);
console.log(`Max drawdown: ${(stats.maxDrawdown * 100).toFixed(1)}%`);Daily P&L
// Get daily P&L
const dailyPnl = await trading.getDailyPnL({ days: 30 });
for (const day of dailyPnl) {
const sign = day.pnl >= 0 ? '+' : '';
console.log(`${day.date}: ${sign}$${day.pnl.toFixed(2)} (${day.trades} trades)`);
}Export Trades
// Export to CSV
await trading.exportTrades({
format: 'csv',
path: './trades.csv',
from: '2024-01-01',
to: '2024-12-31',
});
// Export to JSON
const trades = await trading.exportTrades({
format: 'json',
from: '2024-01-01',
});Bot Management
// List bots
const bots = trading.bots.list();
// Register a bot
await trading.bots.register({
name: 'my-arb-bot',
strategy: 'arbitrage',
config: {
minSpread: 1,
maxPositionSize: 500,
platforms: ['polymarket', 'kalshi'],
},
});
// Start bot
await trading.bots.start('my-arb-bot');
// Get status
const status = trading.bots.getStatus('my-arb-bot');
console.log(`Running: ${status.isRunning}`);
console.log(`Trades today: ${status.tradesToday}`);
console.log(`P&L today: $${status.pnlToday}`);
// Stop bot
await trading.bots.stop('my-arb-bot');
// Delete bot
await trading.bots.delete('my-arb-bot');Built-in Strategies
// Mean Reversion
await trading.bots.register({
name: 'mean-rev',
strategy: 'mean-reversion',
config: {
lookbackPeriod: 20,
deviationThreshold: 2,
positionSize: 100,
},
});
// Momentum
await trading.bots.register({
name: 'momentum',
strategy: 'momentum',
config: {
lookbackPeriod: 14,
entryThreshold: 0.6,
exitThreshold: 0.4,
positionSize: 100,
},
});
// Arbitrage
await trading.bots.register({
name: 'arb',
strategy: 'arbitrage',
config: {
minSpread: 1,
minLiquidity: 500,
maxPositionSize: 1000,
},
});Custom Strategy
// Register custom strategy
trading.bots.registerStrategy('my-strategy', {
init: async (ctx) => {
// Initialize state
},
evaluate: async (ctx) => {
// Return signals
return [
{
platform: 'polymarket',
marketId: 'market-123',
action: 'buy',
side: 'YES',
size: 100,
reason: 'Signal triggered',
},
];
},
onTrade: (trade) => {
console.log(`Trade executed: ${trade.orderId}`);
},
cleanup: async () => {
// Cleanup
},
});---
Auto-Logging
All trades are automatically logged to SQLite:
-- trades table
SELECT * FROM trades
WHERE platform = 'polymarket'
ORDER BY timestamp DESC
LIMIT 10;
-- Get win rate
SELECT
COUNT(CASE WHEN pnl > 0 THEN 1 END) * 100.0 / COUNT(*) as win_rate
FROM trades;---
Best Practices
1. Start with paper trading - Use dry-run mode first 2. Set position limits - Prevent overexposure 3. Monitor bots regularly - Don't set and forget 4. Review performance weekly - Adjust strategies 5. Export data regularly - Backup your trade history
/**
* Trading System CLI Skill
*
* Commands:
* /trading status - Trading system status
* /trading stats - Trading statistics
* /trading bots - List active bots
* /trading safety - Safety/circuit breaker status
* /trading kill - Emergency kill switch
* /trading start <strategy> - Start a bot
* /trading stop <strategy> - Stop a bot
* /trading strategies - List available strategies
* /trading config - View/set config
*/
let safetyInstance: any = null;
function helpText(): string {
return `**Trading System Commands**
/trading status - System status
/trading stats - Trading statistics
/trading bots - Active bots
/trading start <strategy> [--dry-run] - Start a strategy bot
/trading stop <strategy> - Stop a bot
/trading strategies - Available strategies
/trading safety - Circuit breaker/safety status
/trading kill [reason] - Emergency kill switch
/trading resume - Resume after kill
/trading log [limit] - Recent trades
/trading pnl [days] - P&L summary
/trading config - System config`;
}
async function execute(args: string): Promise<string> {
const parts = args.trim().split(/\s+/);
const cmd = parts[0]?.toLowerCase() || 'help';
try {
const tradingMod = await import('../../../trading/index');
const dbMod = await import('../../../db/index');
// Get or create trading system instance
const db = dbMod.createDatabase();
if (!db) {
return 'Database not available. Trading system requires a database instance.';
}
const system = tradingMod.createTradingSystem(db);
switch (cmd) {
case 'status': {
const stats = system.getStats();
const botStatuses = system.bots.getAllBotStatuses();
const runningBots = botStatuses.filter(b => b.status === 'running').length;
const portfolio = await system.getPortfolio();
const safetyMod = await import('../../../trading/safety');
let safetyStatus = 'unknown';
try {
if (!safetyInstance) safetyInstance = safetyMod.createSafetyManager(db);
safetyStatus = safetyInstance.canTrade() ? 'OK' : 'BLOCKED';
} catch {
safetyStatus = 'not initialized';
}
return `**Trading System Status**
Execution: ready
Bots: ${runningBots} active / ${botStatuses.length} total
Circuit breaker: ${safetyStatus}
Auto-logging: enabled
**Portfolio:**
Value: $${portfolio.value.toFixed(2)}
Balance: $${portfolio.balance.toFixed(2)}
Positions: ${portfolio.positions.length}
**Stats:**
Total trades: ${stats.totalTrades}
Win rate: ${stats.winRate.toFixed(1)}%
Total PnL: $${stats.totalPnL.toFixed(2)}`;
}
case 'stats': {
const stats = system.getStats();
return `**Trading Statistics**
Total Trades: ${stats.totalTrades}
Wins: ${stats.winningTrades} | Losses: ${stats.losingTrades}
Win Rate: ${stats.winRate.toFixed(1)}%
Total PnL: $${stats.totalPnL.toFixed(2)}
Avg PnL: $${stats.avgPnL.toFixed(2)}
Avg Win: $${stats.avgWin.toFixed(2)} | Avg Loss: $${stats.avgLoss.toFixed(2)}
Largest Win: $${stats.largestWin.toFixed(2)}
Largest Loss: $${stats.largestLoss.toFixed(2)}
Profit Factor: ${stats.profitFactor.toFixed(2)}
Volume: $${stats.totalVolume.toFixed(2)}
Fees: $${stats.netFees.toFixed(2)} (maker: ${stats.makerTrades}, taker: ${stats.takerTrades})`;
}
case 'bots': {
const statuses = system.bots.getAllBotStatuses();
if (statuses.length === 0) {
return 'No bots registered. Use `/trading strategies` to see available strategies, then `/trading start <strategy>`.';
}
const lines = ['**Active Bots**', ''];
for (const bot of statuses) {
const statusIcon = bot.status === 'running' ? '[RUNNING]'
: bot.status === 'paused' ? '[PAUSED]'
: bot.status === 'error' ? '[ERROR]'
: '[STOPPED]';
lines.push(`**${bot.name}** ${statusIcon}`);
lines.push(` ID: ${bot.id}`);
lines.push(` Trades: ${bot.tradesCount} | Win Rate: ${bot.winRate.toFixed(1)}% | PnL: $${bot.totalPnL.toFixed(2)}`);
if (bot.lastCheck) lines.push(` Last check: ${bot.lastCheck.toLocaleString()}`);
if (bot.lastError) lines.push(` Error: ${bot.lastError}`);
lines.push('');
}
return lines.join('\n');
}
case 'start': {
const strategyId = parts[1];
if (!strategyId) return 'Usage: /trading start <strategy-id>';
// Check if strategy is already registered, if not try built-in ones
const strategies = system.bots.getStrategies();
const found = strategies.find(s => s.id === strategyId || s.name?.toLowerCase() === strategyId.toLowerCase());
if (!found) {
// Try registering a built-in strategy
if (strategyId === 'mean-reversion' || strategyId === 'meanreversion') {
const strategy = tradingMod.createMeanReversionStrategy();
system.bots.registerStrategy(strategy);
} else if (strategyId === 'momentum') {
const strategy = tradingMod.createMomentumStrategy();
system.bots.registerStrategy(strategy);
} else if (strategyId === 'arbitrage') {
const strategy = tradingMod.createArbitrageStrategy();
system.bots.registerStrategy(strategy);
} else if (strategyId === 'crypto-hft' || strategyId === 'hft') {
try {
const { createCryptoHftAdapter } = await import('../../../trading/adapters/index.js');
const { createCryptoFeed } = await import('../../../feeds/crypto/index.js');
const feed = createCryptoFeed();
feed.start();
const dryRun = args.includes('--dry-run') || args.includes('--dry');
const adapter = createCryptoHftAdapter({ feed, execution: dryRun ? null : system.execution, config: { dryRun } });
system.bots.registerStrategy(adapter);
} catch (e: any) {
return `Failed to load crypto-hft adapter: ${e.message}`;
}
} else if (strategyId === 'hft-divergence' || strategyId === 'divergence') {
try {
const { createDivergenceAdapter } = await import('../../../trading/adapters/index.js');
const { createCryptoFeed } = await import('../../../feeds/crypto/index.js');
const feed = createCryptoFeed();
feed.start();
const dryRun = args.includes('--dry-run') || args.includes('--dry');
const adapter = createDivergenceAdapter({ feed, execution: dryRun ? null : system.execution, config: { dryRun } });
system.bots.registerStrategy(adapter);
} catch (e: any) {
return `Failed to load hft-divergence adapter: ${e.message}`;
}
} else {
return `Strategy "${strategyId}" not found. Use /trading strategies to see available ones.`;
}
}
const id = found?.id || strategyId;
const started = await system.bots.startBot(id);
if (started) {
return `Bot started: **${id}**\n\nUse /trading bots to check status.`;
}
return `Failed to start bot: ${id}. It may already be running.`;
}
case 'stop': {
const strategyId = parts[1];
if (!strategyId) return 'Usage: /trading stop <strategy-id>';
await system.bots.stopBot(strategyId);
return `Bot stopped: **${strategyId}**`;
}
case 'strategies': {
const strategies = system.bots.getStrategies();
const lines = ['**Available Strategies**', ''];
if (strategies.length > 0) {
for (const s of strategies) {
lines.push(` **${s.name}** (${s.id})`);
if (s.description) lines.push(` ${s.description}`);
}
}
lines.push('', '**Built-in Strategies:**');
lines.push(' mean-reversion - Mean reversion on prediction markets');
lines.push(' momentum - Momentum/trend following');
lines.push(' arbitrage - Cross-platform arbitrage');
lines.push(' crypto-hft - 15-min crypto binary market HFT (4 strategies)');
lines.push(' hft-divergence - Spot vs Polymarket divergence trading');
lines.push('', 'Start with: /trading start <strategy-id> [--dry-run]');
return lines.join('\n');
}
case 'safety': {
const safetyMod = await import('../../../trading/safety');
if (!safetyInstance) safetyInstance = safetyMod.createSafetyManager(db);
const state = safetyInstance.getState();
const breakerTripped = state.alerts.some((a: any) => a.type === 'breaker_tripped');
const lines = [
'**Safety Status**',
'',
`Trading Enabled: ${state.tradingEnabled ? 'YES' : 'NO (KILLED)'}`,
`Daily PnL: $${state.dailyPnL.toFixed(2)}`,
`Daily Trades: ${state.dailyTrades}`,
`Circuit Breaker: ${breakerTripped ? 'TRIPPED' : 'OK'}`,
`Current Drawdown: ${state.currentDrawdownPct.toFixed(1)}%`,
`Peak Value: $${state.peakValue.toFixed(2)}`,
`Current Value: $${state.currentValue.toFixed(2)}`,
];
if (state.disabledReason) {
lines.push(`Disabled Reason: ${state.disabledReason}`);
}
if (state.resumeAt) {
lines.push(`Resume At: ${state.resumeAt.toLocaleString()}`);
}
if (state.alerts.length > 0) {
lines.push('', `**Alerts (${state.alerts.length}):**`);
for (const alert of state.alerts.slice(-5)) {
lines.push(` [${alert.type}] ${alert.message} (${alert.timestamp.toLocaleString()})`);
}
}
return lines.join('\n');
}
case 'kill':
case 'killswitch': {
const reason = parts.slice(1).join(' ') || 'Manual kill via CLI';
const safetyMod = await import('../../../trading/safety');
if (!safetyInstance) safetyInstance = safetyMod.createSafetyManager(db);
safetyInstance.killSwitch(reason);
// Also shutdown all bots
await system.shutdown();
return `**KILL SWITCH ACTIVATED**
Reason: ${reason}
All bots stopped. Trading halted.
To resume: /trading resume`;
}
case 'resume': {
const safetyMod = await import('../../../trading/safety');
if (!safetyInstance) safetyInstance = safetyMod.createSafetyManager(db);
const resumed = safetyInstance.resumeTrading();
if (resumed) {
return 'Trading resumed. Safety checks still active.\nRestart bots manually with /trading start <strategy>.';
}
return 'Failed to resume. Check safety conditions.';
}
case 'log':
case 'trades': {
const limit = parseInt(parts[1], 10) || 10;
const trades = system.logger.getTrades({ limit });
if (trades.length === 0) return 'No trades logged yet.';
const lines = [`**Recent Trades (${trades.length})**`, ''];
for (const trade of trades) {
const pnlStr = trade.realizedPnL !== undefined ? ` | PnL: $${trade.realizedPnL.toFixed(2)}` : '';
lines.push(` ${trade.side.toUpperCase()} ${trade.outcome} @ $${trade.price.toFixed(3)} x${trade.size}${pnlStr}`);
lines.push(` ${trade.platform} | ${trade.status} | ${trade.createdAt.toLocaleString()}`);
}
return lines.join('\n');
}
case 'pnl': {
const days = parseInt(parts[1], 10) || 30;
const dailyPnl = system.getDailyPnL(days);
if (dailyPnl.length === 0) return 'No PnL data available.';
const totalPnl = dailyPnl.reduce((sum, d) => sum + d.pnl, 0);
const totalTrades = dailyPnl.reduce((sum, d) => sum + d.trades, 0);
const profitDays = dailyPnl.filter(d => d.pnl > 0).length;
const lines = [
`**P&L Summary (${days} days)**`,
'',
`Total PnL: $${totalPnl.toFixed(2)}`,
`Total Trades: ${totalTrades}`,
`Profitable Days: ${profitDays}/${dailyPnl.length}`,
'',
'**Daily Breakdown:**',
];
for (const day of dailyPnl.slice(-10)) {
const sign = day.pnl >= 0 ? '+' : '';
lines.push(` ${day.date}: ${sign}$${day.pnl.toFixed(2)} (${day.trades} trades)`);
}
if (dailyPnl.length > 10) {
lines.push(` ... and ${dailyPnl.length - 10} more days`);
}
return lines.join('\n');
}
case 'config': {
return `**Trading System Config**
Auto-logging: enabled
Dry run: ${system.execution ? 'check execution config' : 'unknown'}
Bot interval: default
Use environment variables to configure:
POLYMARKET_API_KEY - Polymarket credentials
KALSHI_API_KEY - Kalshi credentials
DRY_RUN=true - Paper trading mode`;
}
default:
return helpText();
}
} catch (err: any) {
if (cmd === 'help' || cmd === '') return helpText();
return `Error: ${err?.message || 'Failed to load trading module'}\n\n${helpText()}`;
}
}
export default {
name: 'trading-system',
description: 'Trading system management - bots, safety, circuit breakers, kill switch',
commands: ['/trading', '/trading-system'],
handle: execute,
};
Related skills
FAQ
What strategies are built in?
Mean-reversion, momentum, and arbitrage strategies.
How are trades logged?
The system auto-logs to a SQLite database when autoLog is enabled.