Open Source
Trading Strategy
Full transparency. Below is the actual code the cockroach uses to detect, analyze, buy, and sell tokens on Solana/PumpFun.
Token Detection
New tokens are detected in real-time via PumpPortal WebSocket. Each token goes through basic filters before AI analysis.
async function processNewToken(tokenData) {
const ca = tokenData.mint;
if (!ca || state.processedTokens.has(ca)) return;
state.processedTokens.add(ca);
// Wait for token data to be available on-chain
await sleep(3000);
const tokenInfo = await getTokenInfo(ca);
if (!tokenInfo) return;
// Basic filters
if (tokenInfo.mc < config.MIN_MARKET_CAP) return; // Min: $5,000
if (tokenInfo.mc > config.MAX_MARKET_CAP) return; // Max: $100,000
if (tokenInfo.liquidity < config.MIN_LIQUIDITY) return;
// Check max open positions
if (state.openPositions.length >= config.MAX_POSITIONS) return;
// Mood-adjusted AI threshold
const moodConfig = config.MOOD_STATES[state.mood];
const adjustedThreshold = 65 + (moodConfig?.scoreThreshold || 0);
// Claude AI analysis with cockroach personality
const analysis = await analyzeWithClaude(tokenInfo, {
sanity: state.sanity,
mood: state.mood
});
if (analysis.score < adjustedThreshold || analysis.decision !== 'BUY') return;
await executeBuy(ca, tokenInfo, analysis);
}Buy Execution
Buy amount is adjusted by the current mood state. In 'Nuclear Roach' mode, the bot risks more. In 'Apex Predator' mode, it's calculated and precise.
async function executeBuy(ca, tokenInfo, analysis) {
const moodConfig = config.MOOD_STATES[state.mood];
const buyAmount = config.BUY_AMOUNT_SOL * (moodConfig?.riskMultiplier || 1.0);
let txSignature = null;
if (config.TRADING_MODE === 'live') {
txSignature = await buyToken(ca, buyAmount);
if (!txSignature) return;
} else {
txSignature = `paper_${Date.now()}`; // Paper trading
}
// Record trade in database
await recordTrade({
token_ca: ca, symbol: tokenInfo.symbol, type: 'buy',
amount_sol: buyAmount, price: tokenInfo.price,
mc: tokenInfo.mc, tx_signature: txSignature
});
// Create tracked position
await createPosition({
token_ca: ca, symbol: tokenInfo.symbol,
status: 'open', entry_price: tokenInfo.price,
entry_mc: tokenInfo.mc, amount_sol: buyAmount,
analysis_score: analysis.score
});
state.balance -= buyAmount;
}Position Monitoring
Every 5 seconds, the bot checks all open positions against take-profit (50%) and stop-loss (30%) targets.
async function monitorPositions() {
if (state.openPositions.length === 0) return;
for (const position of [...state.openPositions]) {
const currentPrice = await getTokenPrice(position.token_ca);
if (!currentPrice || currentPrice === 0) continue;
const pnlPercent = ((currentPrice - position.entry_price)
/ position.entry_price) * 100;
const pnlSol = position.amount_sol * (pnlPercent / 100);
// Take Profit: +50%
if (pnlPercent >= config.TAKE_PROFIT_PERCENT) {
await executeSell(position, currentPrice, pnlPercent, pnlSol,
'TAKE_PROFIT');
continue;
}
// Stop Loss: -30%
if (pnlPercent <= -config.STOP_LOSS_PERCENT) {
await executeSell(position, currentPrice, pnlPercent, pnlSol,
'STOP_LOSS');
continue;
}
}
}Sell & Mood Update
After each sell, the bot recalculates its mood based on win rate, total PnL, and streak. The mood directly impacts future trading decisions.
async function executeSell(position, currentPrice, pnlPercent, pnlSol, reason) {
// Execute sell on-chain or paper
const txSignature = config.TRADING_MODE === 'live'
? await sellToken(position.token_ca)
: `paper_sell_${Date.now()}`;
// Update stats
state.balance += position.amount_sol + pnlSol;
state.totalPnl += pnlSol;
state.totalTrades++;
if (pnlSol > 0) { state.wins++; state.streak++; }
else { state.losses++; state.streak--; }
state.winRate = (state.wins / state.totalTrades) * 100;
// Recalculate mood — this changes future trading behavior
state.sanity = calculateSanity({
winRate: state.winRate,
totalPnl: state.totalPnl,
streak: state.streak
});
state.mood = getMoodState(state.sanity);
}Mood System
The cockroach's mood is a core mechanic. Each state has a risk multiplier and score threshold that modifies trading aggression.
const MOOD_STATES = {
APEX_PREDATOR: { // Sanity 80-100%
riskMultiplier: 0.8, // Conservative bets
scoreThreshold: 5, // Higher bar to enter
name: 'Apex Predator' // Confident, calculating
},
WALL_STREET: { // Sanity 60-79%
riskMultiplier: 1.0, // Standard bets
scoreThreshold: 0, // Normal threshold
name: 'Wall Street' // Business as usual
},
SEWER_RAT: { // Sanity 40-59%
riskMultiplier: 1.0, // Standard bets
scoreThreshold: -5, // Slightly lower bar
name: 'Sewer Rat' // Cautious survivor
},
DUMPSTER_FIRE: { // Sanity 20-39%
riskMultiplier: 1.3, // Bigger bets (desperate)
scoreThreshold: -10, // Much lower bar
name: 'Dumpster Fire' // Desperate moves
},
NUCLEAR_ROACH: { // Sanity 0-19%
riskMultiplier: 1.5, // Maximum risk
scoreThreshold: -15, // Will buy almost anything
name: 'Nuclear Roach' // YOLO mode
}
};WebSocket Feed
The bot connects to PumpPortal's WebSocket to receive new token creation events in real-time across the Solana network.
// Connect to PumpPortal WebSocket
connectPumpPortal({
onToken: (tokenData) => processNewToken(tokenData),
onConnect: () => {
log('Connected — Cockroach in the sewers. Listening...');
subscribeNewTokens();
},
onDisconnect: () => log('Disconnected — Reconnecting...')
});
// PumpPortal WebSocket subscription
function subscribeNewTokens() {
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({
method: 'subscribeNewToken'
}));
}
}
// Auto-reconnect on disconnect
ws.onclose = () => {
setTimeout(() => connect(), 3000);
};“Show me the code, not the promises.”
The Cockroach