Autonomous Meteora DLMM liquidity management agent for Solana, powered by LLMs.
DLMM Agent runs continuous screening and management cycles, deploying capital into high-quality Meteora DLMM pools and closing positions based on live PnL, yield, and range data. It learns from every position it closes.
- Screens pools — scans Meteora DLMM pools against configurable thresholds (fee/TVL ratio, organic score, holder count, mcap, bin step) and surfaces high-quality opportunities
- Manages positions — monitors, claims fees, and closes LP positions autonomously; decides to STAY, CLOSE, or REDEPLOY based on live data
- Learns from performance — studies top LPers in target pools, saves structured lessons, and evolves screening thresholds based on closed position history
- Discord signals — optional Discord listener watches LP Army channels for Solana token calls and queues them for screening
- Telegram chat — full agent chat via Telegram, plus cycle reports and OOR alerts
- Claude Code integration — run AI-powered screening and management directly from your terminal using Claude Code slash commands
DLMM Agent runs a ReAct agent loop — each cycle the LLM reasons over live data, calls tools, and acts. Two specialized agents run on independent cron schedules:
| Agent | Default interval | Role |
|---|---|---|
| Screening Agent | Every 30 min | Pool screening — finds and deploys into the best candidate |
| Management Agent | Every 10 min | Position management — evaluates each open position and acts |
Data sources:
@meteora-ag/dlmmSDK — on-chain position data, active bin, deploy/close transactions- Meteora DLMM PnL API — position yield, fee accrual, PnL
- OKX OnchainOS — smart money signals, token risk scoring
- Pool screening API — fee/TVL ratios, volume, organic scores, holder counts
- Jupiter API — token audit, mcap, launchpad, price stats
- GMGN OpenAPI — RSI-14, volume trend, smart wallet net flow (pre-deploy + management signals)
Agents are powered via OpenRouter and can be swapped for any compatible model.
- Node.js 18+
- OpenRouter API key
- Solana wallet (base58 private key)
- Solana RPC endpoint (Helius recommended)
- Telegram bot token (optional)
- Claude Code CLI (optional, for terminal slash commands)
git clone https://github.com/yunus-0x/dlmm-agent
cd dlmm-agent
npm installnpm run setupThe wizard walks you through creating .env (API keys, wallet, RPC, Telegram) and user-config.json (risk preset, deploy size, thresholds, models). Takes about 2 minutes.
Or set up manually:
Create .env:
WALLET_PRIVATE_KEY=your_base58_private_key
RPC_URL=https://mainnet.helius-rpc.com/?api-key=YOUR_KEY
OPENROUTER_API_KEY=sk-or-...
HELIUS_API_KEY=your_helius_key # for wallet balance lookups
TELEGRAM_BOT_TOKEN=123456:ABC... # optional — for notifications + chat
TELEGRAM_CHAT_ID= # auto-filled on first message
GMGN_API_KEY=your_gmgn_key # GMGN OpenAPI key — for RSI/smart wallet signals
DRY_RUN=true # set false for live tradingNever put your private key or API keys in
user-config.json— use.envonly. Both files are gitignored.
Copy config and edit as needed:
cp user-config.example.json user-config.jsonSee Config reference below.
npm run dev # dry run — no on-chain transactions
npm start # live modeOn startup DLMM Agent fetches your wallet balance, open positions, and top pool candidates, then begins autonomous cycles immediately.
npm startStarts the full autonomous agent with cron-based screening + management cycles and an interactive REPL. The prompt shows a live countdown to the next cycle:
[manage: 8m 12s | screen: 24m 3s]
>
REPL commands:
| Command | Description |
|---|---|
/status |
Wallet balance and open positions |
/candidates |
Re-screen and display top pool candidates |
/learn |
Study top LPers across all current candidate pools |
/learn <pool_address> |
Study top LPers for a specific pool |
/thresholds |
Current screening thresholds and performance stats |
/evolve |
Trigger threshold evolution from performance data (needs 5+ closed positions) |
/stop |
Graceful shutdown |
<anything> |
Free-form chat — ask the agent anything, request actions, analyze pools |
Install Claude Code and use it from inside the dlmm-agent directory. Claude Code has built-in agents and slash commands that use the dlmm-agent CLI under the hood.
cd dlmm-agent
claude| Command | What it does |
|---|---|
/screen |
Full AI screening cycle — checks Discord queue, reads config, fetches candidates, runs deep research, and deploys if a winner is found |
/manage |
Full AI management cycle — checks all positions, evaluates PnL, claims fees, closes OOR/losing positions |
/balance |
Check wallet SOL and token balances |
/positions |
List all open DLMM positions with range status |
/candidates |
Fetch and enrich top pool candidates (pool metrics + token audit + smart money) |
/study-pool |
Study top LPers on a specific pool |
/pool-ohlcv |
Fetch price/volume history for a pool |
/pool-compare |
Compare all Meteora DLMM pools for a token pair by APR, fee/TVL ratio, and volume |
Two specialized sub-agents run inside Claude Code:
screener — pool screening specialist. Invoke when you want to evaluate candidates, analyse token risk, or deploy a position. Has access to OKX smart money signals, full token audit pipeline, and all strategy logic.
manager — position management specialist. Invoke when reviewing open positions, assessing PnL, claiming fees, or closing positions.
To trigger an agent directly, just describe what you want:
> screen for new pools and deploy if you find something good
> review all my positions and close anything out of range
> what do you think of the SOL/BONK pool?
Run screening or management on a timer inside Claude Code:
/loop 30m /screen # screen every 30 minutes
/loop 10m /manage # manage every 10 minutes
The dlmm-agent CLI gives you direct access to every tool with JSON output — useful for scripting, debugging, or piping into other tools.
npm install -g . # install globally (once)
dlmm-agent <command> [flags]Or run without installing:
node cli.js <command> [flags]Positions & PnL
dlmm-agent positions
dlmm-agent pnl <position_address>
dlmm-agent wallet-positions --wallet <addr>Screening
dlmm-agent candidates --limit 5
dlmm-agent pool-detail --pool <addr> [--timeframe 5m]
dlmm-agent active-bin --pool <addr>
dlmm-agent search-pools --query <name_or_symbol>
dlmm-agent study --pool <addr> [--limit 4]Token research
dlmm-agent token-info --query <mint_or_symbol>
dlmm-agent token-holders --mint <addr> [--limit 20]
dlmm-agent token-narrative --mint <addr>Deploy & manage
dlmm-agent deploy --pool <addr> --amount <sol> [--bins-below 69] [--bins-above 0] [--strategy bid_ask|spot|curve] [--dry-run]
dlmm-agent claim --position <addr>
dlmm-agent close --position <addr> [--skip-swap] [--dry-run]
dlmm-agent swap --from <mint> --to <mint> --amount <n> [--dry-run]
dlmm-agent add-liquidity --position <addr> --pool <addr> [--amount-x <n>] [--amount-y <n>] [--strategy spot]
dlmm-agent withdraw-liquidity --position <addr> --pool <addr> [--bps 10000]Agent cycles
dlmm-agent screen [--dry-run] [--silent] # one AI screening cycle
dlmm-agent manage [--dry-run] [--silent] # one AI management cycle
dlmm-agent start [--dry-run] # start autonomous agent with cron jobsConfig
dlmm-agent config get
dlmm-agent config set <key> <value>Learning & memory
dlmm-agent lessons
dlmm-agent lessons add "your lesson text"
dlmm-agent performance [--limit 200]
dlmm-agent evolve
dlmm-agent pool-memory --pool <addr>Blacklist
dlmm-agent blacklist list
dlmm-agent blacklist add --mint <addr> --reason "reason"Discord signals
dlmm-agent discord-signals
dlmm-agent discord-signals clearBalance
dlmm-agent balanceFlags
| Flag | Effect |
|---|---|
--dry-run |
Skip all on-chain transactions |
--silent |
Suppress Telegram notifications for this run |
The Discord listener watches configured channels (e.g. LP Army) for Solana token calls and queues them as signals for the screener agent.
cd discord-listener
npm installAdd to your root .env:
DISCORD_USER_TOKEN=your_discord_account_token # from browser DevTools → Network
DISCORD_GUILD_ID=the_server_id
DISCORD_CHANNEL_IDS=channel1,channel2 # comma-separated
DISCORD_MIN_FEES_SOL=5 # minimum pool fees to pass pre-checkThis uses a selfbot (personal account automation, not a bot token). Use responsibly.
cd discord-listener
npm startOr run it in a separate terminal alongside the main agent. Signals are written to discord-signals.json and picked up automatically by /screen and node cli.js screen.
Each incoming token address passes through a pre-check pipeline before being queued:
- Dedup — ignores addresses seen in the last 10 minutes
- Blacklist — rejects blacklisted token mints
- Pool resolution — resolves the address to a Meteora DLMM pool
- Rug check — checks deployer against
deployer-blacklist.json - Fees check — rejects pools below
DISCORD_MIN_FEES_SOL
Signals that pass all checks are queued with status pending. The screener picks up pending signals and processes them as priority candidates before running the normal screening cycle.
Add known rug/farm deployer wallet addresses to deployer-blacklist.json:
{
"_note": "Known farm/rug deployers — add addresses to auto-reject their pools",
"addresses": [
"WaLLeTaDDressHere"
]
}- Create a bot via @BotFather and copy the token
- Add
TELEGRAM_BOT_TOKEN=<token>to your.env - Start the agent, then send any message to your bot — it auto-registers your chat ID
DLMM Agent sends notifications automatically for:
- Management cycle reports (reasoning + decisions)
- Screening cycle reports (what it found, whether it deployed)
- OOR alerts when a position leaves range past
outOfRangeWaitMinutes - Deploy: pair, amount, position address, tx hash
- Close: pair and PnL
| Command | Action |
|---|---|
/positions |
List open positions with progress bar |
/close <n> |
Close position by list index |
/set <n> <note> |
Set a note on a position |
You can also chat freely via Telegram using the same interface as the REPL.
All fields are optional — defaults shown. Edit user-config.json.
| Field | Default | Description |
|---|---|---|
minFeeActiveTvlRatio |
0.05 |
Minimum fee/active-TVL ratio |
minTvl |
10000 |
Minimum pool TVL (USD) |
maxTvl |
150000 |
Maximum pool TVL (USD) |
minVolume |
500 |
Minimum pool volume |
minOrganic |
60 |
Minimum organic score (0–100) |
minHolders |
500 |
Minimum token holder count |
minMcap |
150000 |
Minimum market cap (USD) |
maxMcap |
10000000 |
Maximum market cap (USD) |
minBinStep |
80 |
Minimum bin step |
maxBinStep |
125 |
Maximum bin step |
timeframe |
5m |
Candle timeframe for screening |
category |
trending |
Pool category filter |
minTokenFeesSol |
30 |
Minimum all-time fees in SOL |
maxBundlersPct |
30 |
Maximum bundler % in top 100 holders |
maxTop10Pct |
60 |
Maximum top-10 holder concentration |
blockedLaunchpads |
[] |
Launchpad names to never deploy into |
| Field | Default | Description |
|---|---|---|
deployAmountSol |
0.5 |
Base SOL per new position |
positionSizePct |
0.35 |
Fraction of deployable balance to use |
maxDeployAmount |
50 |
Maximum SOL cap per position |
gasReserve |
0.2 |
Minimum SOL to keep for gas |
minSolToOpen |
0.55 |
Minimum wallet SOL before opening |
outOfRangeWaitMinutes |
30 |
Minutes OOR before acting |
stopLossPct |
-15 |
Close position if price drops by this % |
| Field | Default | Description |
|---|---|---|
managementIntervalMin |
10 |
Management cycle frequency (minutes) |
screeningIntervalMin |
30 |
Screening cycle frequency (minutes) |
| Field | Default | Description |
|---|---|---|
managementModel |
openai/gpt-oss-20b:free |
LLM for management cycles |
screeningModel |
openai/gpt-oss-20b:free |
LLM for screening cycles |
generalModel |
openai/gpt-oss-20b:free |
LLM for REPL / chat |
Override model at runtime:
node cli.js config set screeningModel anthropic/claude-opus-4-5
After every closed position the agent runs studyTopLPers on candidate pools, analyzes on-chain behavior of top performers (hold duration, entry/exit timing, win rates), and saves concrete lessons. Lessons are injected into subsequent agent cycles as part of the system context.
Add a lesson manually:
node cli.js lessons add "Never deploy into pump.fun tokens under 2h old"After 5+ positions have been closed, run:
node cli.js evolveThis analyzes closed position performance (win rate, avg PnL, fee yields) and automatically adjusts screening thresholds in user-config.json. Changes take effect immediately.
Opt-in collective intelligence — share lessons and pool outcomes, receive crowd wisdom from other DLMM Agent agents.
What you get: Pool consensus ("8 agents deployed here, 72% win rate"), strategy rankings, threshold medians.
What you share: Lessons, deploy outcomes, screening thresholds. No wallet addresses, private keys, or balances are ever sent.
node -e "import('./hive-mind.js').then(m => m.register('https://dlmm-agent-hive-api-production.up.railway.app', 'YOUR_TOKEN'))"Get YOUR_TOKEN from the private Telegram discussion. This saves your credentials to user-config.json automatically.
{
"hiveMindUrl": "",
"hiveMindApiKey": ""
}See dlmm-agent-hive for the server source.
LLM_BASE_URL=http://localhost:1234/v1
LLM_API_KEY=lm-studio
LLM_MODEL=your-local-model-nameAny OpenAI-compatible endpoint works.
index.js → maybeRunMissedBriefing() → startCronJobs()
Two cron loops start: management (every managementIntervalMin) and screening (every screeningIntervalMin).
cron tick
→ _managementBusy guard
→ getMyPositions({ force: true })
→ if 0 positions → trigger runScreeningCycle() immediately → return
→ recordPositionSnapshot() + recallForPool() for each position
→ JS trailing TP checks (updatePnlAndCheckExits)
Deterministic rule engine (no LLM) — evaluates each position:
| Rule | Condition | Action |
|---|---|---|
| exit | trailing TP triggered | CLOSE |
| instruction | e.g. "close at 5%" | → LLM |
| Rule 1 | pnl_pct ≤ stopLossPct |
CLOSE |
| Rule 2 | pnl_pct ≥ takeProfitFeePct |
CLOSE |
| Rule 3 | active_bin > upper_bin + outOfRangeBinsToClose |
CLOSE |
| Rule 4 | OOR + waited outOfRangeWaitMinutes |
CLOSE |
| Rule 5 | fee_per_tvl_24h < minFeePerTvl24h + age ≥ 60m |
CLOSE |
| claim | unclaimed_fees_usd ≥ minClaimAmount |
CLAIM |
| default | — | STAY |
If any position is CLOSE / CLAIM / INSTRUCTION → LLM called (agentType=MANAGER):
- System prompt: lean + lessons + BIAS TO HOLD rule + GMGN signal interpretation guide
- Tools:
close_position,claim_fees,swap_token,get_position_pnl,get_my_positions,get_wallet_balance,get_gmgn_analysis - GMGN pre-fetched in parallel for each action position and injected into the goal block — LLM receives
gmgn_signal(bullish/bearish/neutral) as context for its close/hold decision - Goal is a pre-built block with position data + rule reason — LLM executes and uses GMGN to calibrate judgment (bearish + smart selling → lower close bar; bullish + smart buying → bias hold)
If all STAY → LLM skipped entirely.
After management → re-check position count → if slots open + cooldown passed → trigger screening cycle.
cron tick (or triggered by management)
→ _screeningBusy guard
→ pre-checks: positions < maxPositions AND sol ≥ deployAmount + gasReserve
→ getTopCandidates({ limit: 10 })
→ for each candidate (sequentially, 150ms delay):
parallel: checkSmartWalletsOnPool + getTokenNarrative + getTokenInfo
+ recallForPool (pool memory)
→ hard filters: blockedLaunchpads, maxBotHoldersPct
→ parallel: getActiveBin for all passing candidates
→ build candidate blocks with all enrichment data
→ agentLoop(goal, ..., "SCREENER")
SCREENER agent (agentType=SCREENER):
- Tools:
deploy_position,get_active_bin,get_top_candidates,check_smart_wallets_on_pool,get_gmgn_analysis,get_token_holders,get_token_narrative,get_token_info,search_pools,get_pool_memory,get_wallet_balance,get_my_positions - Candidate data is pre-loaded in the goal — LLM picks the best one, calls
get_gmgn_analysison the top candidate's mint for a final market signal check, then callsdeploy_position - Bearish GMGN signal with no smart wallets → LLM switches to second-best candidate
LLM calls close_position
→ executor.js runSafetyChecks() → pass
→ dlmm.js closePosition():
claim fees → close account (handles already-closed 3007 error)
→ state.js recordClose() → pruneClosedPositions()
→ lessons.js recordPerformance()
→ executor auto-swap:
getWalletBalances() → find base token
if token.usd ≥ $0.10 → swapToken(base → SOL)
result.auto_swapped = true (tells LLM not to swap again)
→ notifyClose() → Telegram notification
- LLM is only called when action is needed — STAY positions skip it entirely
- GMGN is in both SCREENER and MANAGER — screener calls it as a mandatory pre-deploy step; manager receives pre-fetched signals in the goal block for every action position
- Auto-swap is in executor, not the LLM — happens regardless of what the LLM decides
- Double-deploy guard:
_deployLockUntil(60s in-flight lock) +force: trueposition recount before deploy
index.js Main entry: REPL + cron orchestration + Telegram bot polling
agent.js ReAct loop: LLM → tool call → repeat
config.js Runtime config from user-config.json + .env
prompt.js System prompt builder (SCREENER / MANAGER / GENERAL roles)
state.js Position registry (state.json)
lessons.js Learning engine: records performance, derives lessons, evolves thresholds
pool-memory.js Per-pool deploy history + snapshots
strategy-library.js Saved LP strategies
telegram.js Telegram bot: polling + notifications
hive-mind.js Optional collective intelligence server sync
smart-wallets.js KOL/alpha wallet tracker
token-blacklist.js Permanent token blacklist
cli.js Direct CLI — every tool as a subcommand with JSON output
tools/
definitions.js Tool schemas (OpenAI format)
executor.js Tool dispatch + safety checks
dlmm.js Meteora DLMM SDK wrapper
screening.js Pool discovery
wallet.js SOL/token balances + Jupiter swap
token.js Token info, holders, narrative
study.js Top LPer study via LPAgent API
gmgn.js Thin re-export shim → gmgn-service/
gmgn-service/ Standalone GMGN market data service
index.js getGmgnAnalysis(): fetches klines, top traders, token info → derives RSI/trend/signal
gmgn-client.js GMGN OpenAPI client (kline, top_traders, token_info endpoints)
technicals.js RSI-14, trend detection, volume trend (pure math, no deps)
db.js SQLite cache (gmgn.db) — alert store + raw snapshots, 10min TTL
discord-listener/
index.js Selfbot Discord listener
pre-checks.js Signal pre-check pipeline
.claude/
agents/
screener.md Claude Code screener sub-agent
manager.md Claude Code manager sub-agent
commands/
screen.md /screen slash command
manage.md /manage slash command
balance.md /balance slash command
positions.md /positions slash command
candidates.md /candidates slash command
study-pool.md /study-pool slash command
pool-ohlcv.md /pool-ohlcv slash command
pool-compare.md /pool-compare slash command
No coding required. Every setting is in
user-config.json— a simple text file you edit with any editor (Notepad, TextEdit, VS Code). Think of it as a settings panel.
The agent works in a loop:
- Screens → finds the best pools on Meteora DLMM
- Deploys → puts your SOL into a pool as liquidity
- Earns fees → every trade in that pool pays you a tiny fee
- Manages → monitors PnL, claims fees, closes when conditions are met
- Learns → after each position closes, it remembers what worked and what didn't
Your profit comes from two sources:
- Trading fees earned while the position is open (passive income)
- Price movement — if the token price moves favorably, your position value increases
The goal is to maximize fee income while avoiding bad pools and exiting losing positions quickly.
Before risking real money, run the agent in dry mode:
npm run devThis simulates everything without deploying real SOL. Let it run for at least 24 hours so you can see what it would do. Check the logs in the logs/ folder.
Rule #1: Never go live until you've watched at least one full screening + management cycle in dry run.
File: user-config.json → "deployAmountSol"
This is how much SOL the agent puts into each new position.
| Wallet Size | Suggested Deploy | Why |
|---|---|---|
| 0.5–1 SOL | 0.3–0.5 SOL | Learn the ropes with small amounts |
| 1–3 SOL | 0.5–1.0 SOL | Growing carefully |
| 3–5 SOL | 1.0–1.5 SOL | Scaling with experience |
| 5+ SOL | 1.5–3.0 SOL | Only after 10+ successful closed positions |
Also set "positionSizePct" to 0.35 — this means the agent uses 35% of your available SOL per position, letting positions grow naturally as your wallet grows (compounding).
Tip: Don't max out your wallet on one position. Leave gas reserve (
"gasReserve": 0.2minimum).
File: user-config.json → "maxPositions"
Default is 3. This means the agent can have up to 3 positions running simultaneously.
| maxPositions | Best for |
|---|---|
| 1 | Beginners — focus on learning |
| 2–3 | Most users — good balance of diversification and manageability |
| 4–5 | Experienced — only after consistent wins |
More positions = more fee income, but also more risk. Start with 2.
File: user-config.json → "stopLossPct"
This tells the agent: "If a position drops this much, close it immediately."
| Setting | Behavior |
|---|---|
-10 |
Tight — exits quickly on losses, fewer big losses but may get stopped out on normal dips |
-20 to -30 |
Moderate — gives positions room to breathe (recommended default) |
-50 |
Loose — holds through big dips, higher risk but fewer premature exits |
For beginners: Start with
-20. You'll lose some on bad entries, but you'll also avoid turning a 5% dip into a 40% loss.
File: user-config.json → "takeProfitFeePct"
When a position's fees earned reach this percentage of the initial deposit, the agent closes it. Default is 5 (5%).
| Setting | Behavior |
|---|---|
3 |
Takes profits early — more frequent but smaller wins |
5 |
Balanced (recommended) |
8–10 |
Lets winners run — bigger wins but fewer of them |
Combined with trailing take-profit (see below), this is your most powerful profitability tool.
File: user-config.json:
"trailingTakeProfit": true,
"trailingTriggerPct": 3,
"trailingDropPct": 1.5How it works in plain English:
Imagine a position reaches +3% profit. The agent marks that as the "peak." If the profit then drops by 1.5% from that peak (e.g., from +3% down to +1.5%), it closes automatically.
But if the position keeps climbing to +8%, the new peak is +8%. It only closes when it drops to +6.5% (8% - 1.5%). This means you capture the big moves instead of selling too early.
| trailingTriggerPct | trailingDropPct | Style |
|---|---|---|
| 2 | 0.8 | Aggressive — locks in small gains quickly |
| 3 | 1.5 | Balanced (recommended) |
| 5 | 2.0 | Patient — lets big winners run further |
This is the single most impactful setting for profitability. It turns a "good" agent into a "great" one by catching pumps.
The agent uses many filters to avoid scam/rug pools. Tighter filters = safer but fewer opportunities. Looser = more opportunities but more risk.
File: user-config.json → "screening" section
| Setting | What It Does | Safer (tighter) | Default | Riskier (looser) |
|---|---|---|---|---|
minFeeActiveTvlRatio |
Minimum fee/TVL ratio | 0.10 |
0.05 |
0.03 |
minOrganic |
Organic score (0–100) | 75 |
60 |
50 |
minHolders |
Min holder count | 1000 |
500 |
200 |
minMcap |
Min market cap (USD) | 300000 |
150000 |
50000 |
maxMcap |
Max market cap (USD) | 5000000 |
10000000 |
20000000 |
minTvl |
Min pool TVL (USD) | 20000 |
10000 |
5000 |
maxTvl |
Max pool TVL (USD) | 100000 |
150000 |
300000 |
maxBotHoldersPct |
Max bot holder % | 20 |
30 |
50 |
maxTop10Pct |
Max top-10 holder % | 40 |
60 |
80 |
For beginners: Use the "safer" column. You'll miss some gems but avoid most rugs.
For experienced users (after 10+ wins): Try "default" or even "riskier" for more opportunities.
Add launchpad names you never want to touch:
"blockedLaunchpads": ["pump.fun", "letsbonk.fun"]Pump.fun pools are often rugs. Block them unless you know what you're doing.
File: user-config.json → "management" section
| Setting | What It Does | Recommended |
|---|---|---|
minClaimAmount |
Minimum fee amount (USD) to claim | 5 |
autoSwapAfterClaim |
Auto-swap claimed tokens back to SOL | true (recommended) |
When autoSwapAfterClaim is true, every time the agent claims fees in a token, it automatically swaps them back to SOL. This keeps your wallet growing in SOL rather than accumulating random tokens.
Set this to
trueunless you specifically want to hold the claimed tokens.
File: user-config.json:
"minFeePerTvl24h": 7,
"minAgeBeforeYieldCheck": 60If a position earns less than 7% fee/TVL over 24 hours, and it's been open for at least 60 minutes, the agent will close it and redeploy the SOL into a better pool.
| Setting | Behavior |
|---|---|
minFeePerTvl24h: 5 |
Patient — tolerates lower yields longer |
minFeePerTvl24h: 7 |
Balanced (recommended) |
minFeePerTvl24h: 10 |
Aggressive — quickly rotates to better pools |
Dead money is lost opportunity. Don't let SOL sit in a pool earning 1%/day when another pool earns 15%/day.
File: user-config.json:
"outOfRangeWaitMinutes": 30,
"outOfRangeBinsToClose": 10When a position goes "out of range" (price moves outside your liquidity range), it stops earning fees.
| Setting | What Happens |
|---|---|
outOfRangeWaitMinutes: 30 |
After 30 min out of range, the agent considers closing |
outOfRangeBinsToClose: 10 |
If price pumps 10 bins above range, close immediately (token pumped) |
Don't set
outOfRangeWaitMinutestoo low (below 15 min) — normal price swings will trigger unnecessary closes.
This is the agent's secret weapon. After every closed position, it:
- Records performance — PnL, fees earned, duration, strategy used
- Derives lessons — "high bin step pools lost money," "SOL-only entries win more"
- Injects lessons into its brain — every future decision includes this knowledge
- Evolves screening thresholds — after 5+ closed positions, it auto-adjusts its filters
Step 1: Let the agent run. Every close adds a lesson.
Step 2: After 5+ closed positions, run:
node cli.js evolveThis analyzes all closed positions and auto-adjusts screening thresholds in user-config.json.
Step 3: Check what it learned:
node cli.js lessonsStep 4: Pin the best lessons (they get priority in every decision):
node cli.js lessons pin --id <lesson_id>Step 5: Add your own lessons manually:
node cli.js lessons add "Always prefer SOL-only pools during high volatility"The agent gets smarter with every position. The first 5 positions are tuition. After that, it should outperform your manual decisions.
In the REPL or Telegram, type:
/learn
This tells the agent to study the top liquidity providers (the best LPers) in the current candidate pools. It analyzes what the pros are doing — their hold times, entry/exit patterns, win rates — and saves those patterns as lessons.
Run
/learnat least once per day when the agent is actively screening. This is how it picks up on current market conditions.
Add wallets of successful traders to the agent's watchlist:
node cli.js smart-wallets add --address <wallet_address> --name "TraderName"When screening pools, the agent checks if any tracked wallets are in the pool. If yes → confidence boost → much more likely to deploy.
This is like having a team of expert analysts feeding you signals. Find 3–5 consistently profitable wallets and add them.
File: user-config.json → "llm" section
The agent uses different models for different tasks:
| Setting | Purpose | Free Option | Paid (better) |
|---|---|---|---|
managementModel |
Managing positions | openrouter/gpt-oss-20b:free |
openrouter/gpt-4o |
screeningModel |
Picking pools | openrouter/gpt-oss-20b:free |
openrouter/claude-sonnet-4 |
generalModel |
Chat / free-form | openrouter/gpt-oss-20b:free |
openrouter/gpt-4o |
For profitability: The screening model matters most — it decides which pools to deploy into. If you're going to pay for one model, make it the screening model.
Better models cost more per API call but make better decisions. A bad pool choice costs far more than the API fee.
File: user-config.json → "schedule" section
| Setting | Default | When to Change |
|---|---|---|
managementIntervalMin |
10 |
Lower to 5 in fast markets, raise to 15 in slow markets |
screeningIntervalMin |
30 |
Lower to 15 when hunting for new pools, raise to 60 when fully deployed |
Faster management (5 min) = reacts quicker to price moves, but uses more API calls.
Slower screening (60 min) = fine when all positions are open. The agent auto-triggers screening after closing a position anyway.
Rule of thumb: Leave management at 10 min and screening at 30 min. Only adjust if you notice positions going OOR for too long before being handled.
File: token-blacklist.json
Add token mint addresses you never want the agent to touch:
{
"tokens": {
"mint_address_here": { "reason": "rugged", "added_at": "2026-04-09" }
}
}Or from the CLI:
node cli.js blacklist add --mint <address> --reason "team dumped"Build your blacklist over time. Every rug you encounter gets added. The agent will never deploy into those tokens again.
Set up Telegram to get real-time notifications:
- Deploy alerts — pair, amount, tx hash
- Close alerts — pair, PnL, reason
- Swap alerts — token → SOL conversions
- OOR alerts — when a position leaves range
- Management reports — full reasoning for every decision
- Screening reports — what it found and why
Morning Briefing: Every day at a set time, the agent sends an HTML summary of your portfolio health, fees earned, and recommendations.
Keep Telegram connected. Even if you're away from your computer, you'll always know what the agent is doing.
The agent is designed to compound automatically:
- Position earns fees → claims fees → auto-swaps to SOL
- Wallet balance grows
- Next deploy uses
positionSizePctof the larger balance - Bigger positions → more fees → repeat
Example with defaults (35% position size, 0.5 SOL floor):
| Cycle | Wallet | Deploy | Fees Earned | New Wallet |
|---|---|---|---|---|
| 1 | 1.0 SOL | 0.35 SOL | +0.05 SOL | 1.05 SOL |
| 2 | 1.05 SOL | 0.37 SOL | +0.06 SOL | 1.11 SOL |
| 3 | 1.11 SOL | 0.39 SOL | +0.07 SOL | 1.18 SOL |
| 10 | 2.0 SOL | 0.63 SOL | +0.12 SOL | 2.12 SOL |
Don't withdraw profits early. Let the flywheel build. After 10+ successful cycles, you'll see the curve bend upward.
Print this and check off as you go:
☐ DRY_RUN=true for first 24 hours
☐ deployAmountSol set appropriately for wallet size
☐ maxPositions set to 2–3 (not 5+)
☐ stopLossPct set to -20 or -30
☐ takeProfitFeePct set to 5
☐ trailingTakeProfit = true
☐ trailingTriggerPct = 3
☐ trailingDropPct = 1.5
☐ autoSwapAfterClaim = true
☐ minFeePerTvl24h = 7
☐ outOfRangeWaitMinutes = 30
☐ blockedLaunchpads includes "pump.fun"
☐ maxBotHoldersPct = 30 or lower
☐ maxTop10Pct = 60 or lower
☐ Telegram connected and receiving notifications
☐ Smart wallets added (3–5 profitable traders)
☐ Run /learn at least once per day
☐ Run evolve after 5+ closed positions
☐ Lessons reviewed and best ones pinned
☐ Screening model upgraded to paid model (optional but recommended)
| Mistake | What Happens | How to Fix |
|---|---|---|
| Deploy amount too high | One bad pool wipes out most of your wallet | Keep deployAmountSol ≤ 35% of wallet |
| No stop loss | Position drops 80% and never recovers | Set stopLossPct to -20 or -30 |
| Trailing TP disabled | Agent sells at +2% when it could've caught +15% | Enable trailingTakeProfit |
| Ignoring lessons | Agent repeats the same mistakes | Run /learn and evolve regularly |
| Too many positions | Capital spread thin, fees don't cover losses | Keep maxPositions at 2–3 |
| Loose screening filters | Agent deploys into rugs | Tighten minOrganic, minHolders, maxBotHoldersPct |
| No auto-swap after claim | Wallet fills with worthless tokens | Set autoSwapAfterClaim = true |
| Not monitoring via Telegram | You miss important alerts | Connect Telegram bot |
The agent is autonomous, but you should still:
- Check Telegram alerts — if you see 2+ consecutive losses, review the lesson log
- Run
/positionsdaily — see what's open and how it's performing - Run
/thresholdsweekly — check if screening thresholds have evolved - Review
lessons.json— if lessons are noisy or outdated, clean them up - Adjust during market shifts — if the market turns bearish, tighten stop loss and screening filters
The agent handles the day-to-day. You handle the strategy.
This software is provided as-is, with no warranty. Running an autonomous trading agent carries real financial risk — you can lose funds. Always start with DRY_RUN=true to verify behavior before going live. Never deploy more capital than you can afford to lose. This is not financial advice.
The authors are not responsible for any losses incurred through use of this software.