Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
185 commits
Select commit Hold shift + click to select a range
b3abecb
refactor: remove hive-mind feature
yunus-0x Mar 23, 2026
ccfa612
fix: prevent double tool execution (deploy/swap/close twice)
yunus-0x Mar 23, 2026
3d36ca6
fix: remove flip bid-ask leftovers from management prompt
yunus-0x Mar 23, 2026
8e90344
fix: always fetch fresh positions in management/screening cycles
yunus-0x Mar 23, 2026
1320d27
fix: instruction override + remove progress bar from management report
yunus-0x Mar 23, 2026
1585a06
fix: bump management maxOutputTokens 1024→2048 for reasoning models
yunus-0x Mar 23, 2026
5b14d14
fix: eliminate double PnL fetch + expose instruction/fee_per_tvl_24h
yunus-0x Mar 23, 2026
cf4a2ac
refactor: replace getProgramAccounts+per-pool PnL with single portfol…
yunus-0x Mar 23, 2026
2a286f7
perf: slim MANAGER system prompt to cut ~3000+ prompt tokens
yunus-0x Mar 23, 2026
99e9ce0
fix: trigger screening AFTER management cycle completes, not before
yunus-0x Mar 23, 2026
7fd69ab
fix: reduce management cycle reasoning waste
yunus-0x Mar 23, 2026
3abc5df
fix: don't consume once-per-session slot on safety-blocked deploy
yunus-0x Mar 23, 2026
a5aba3f
perf: slash screening token usage — JS pre-filter, drop holders, lean…
yunus-0x Mar 23, 2026
13c6a9c
feat: add in-range/OOR indicator to management report
yunus-0x Mar 23, 2026
382836a
feat: add trailing take-profit
yunus-0x Mar 23, 2026
68807d4
feat: 30s PnL poller for accurate trailing TP state between cycles
yunus-0x Mar 23, 2026
4c3ca74
fix: 429 rate limit + low-yield pool memory note
yunus-0x Mar 23, 2026
b58383a
fix: suppress portfolio fetch log from 30s PnL poller
yunus-0x Mar 23, 2026
05d4770
feat: fetch 10 candidates, pass all to LLM — no hard filter
yunus-0x Mar 23, 2026
3ae3f75
feat: fees_sol as hard rule, top10/bots as soft guidelines in screener
yunus-0x Mar 23, 2026
aabe79b
feat: add solMode — positions and PnL reported in SOL when enabled
yunus-0x Mar 23, 2026
cc47949
feat: add meridian CLI + hoist runManagementCycle/runScreeningCycle t…
yunus-0x Mar 23, 2026
0ff9307
feat: enrich candidates command with token info, holders, smart walle…
yunus-0x Mar 23, 2026
076eada
fix: only lock once-per-session after successful deploy, not on failure
yunus-0x Mar 24, 2026
33c7c59
fix: prevent duplicate BN imports when patch-anchor runs multiple times
yunus-0x Mar 24, 2026
3ca1ac8
refactor: deterministic management cycle — LLM only on action
yunus-0x Mar 24, 2026
481fcaa
fix: re-fetch final value after close if API returns 0 (settlement lag)
yunus-0x Mar 24, 2026
faf2206
fix: correct field names for solMode report + PnL sanity check
yunus-0x Mar 24, 2026
03ee4a7
fix: derive initial_value_usd from final-pnl when not tracked at deploy
yunus-0x Mar 24, 2026
e48ce70
fix: use status=closed API for accurate post-close PnL recording
yunus-0x Mar 24, 2026
a3c67a3
feat: trigger management cycle immediately on PnL poll exit alert
yunus-0x Mar 24, 2026
4a0ae5f
refactor: rename emergencyPriceDropPct to stopLossPct
yunus-0x Mar 24, 2026
899a37e
fix: remove volatility-based interval auto-adjustment
yunus-0x Mar 24, 2026
f584f57
fix: respect managementIntervalMin cooldown on poll-triggered management
yunus-0x Mar 24, 2026
2909b12
fix: poller-triggered management runs silent, cron handles reporting
yunus-0x Mar 24, 2026
32ed5e0
fix: block claim_fees on already-closed positions
yunus-0x Mar 24, 2026
2b1bc22
fix: compact screening report + bump bins_below max to 90
yunus-0x Mar 24, 2026
0595842
fix: use newline-separated screening report format
yunus-0x Mar 24, 2026
8acb837
fix: correct downside formula to (minPrice/maxPrice-1)*100%
yunus-0x Mar 24, 2026
c765157
fix: block re-deployment to pools closed for low yield (4h cooldown)
yunus-0x Mar 25, 2026
29235f3
fix: wait 5s after close txs for RPC balance to settle
yunus-0x Mar 25, 2026
72652c3
fix: skip internal claim in closePosition if recently claimed + fix w…
yunus-0x Mar 25, 2026
ee1e80d
perf: reduce unnecessary LLM steps in management and deploy cycles
yunus-0x Mar 25, 2026
e130a41
fix: remove duplicate const tracked declaration causing TDZ in closeP…
yunus-0x Mar 25, 2026
9a2f4fe
fix: restore tracked declaration in closePosition scope
yunus-0x Mar 25, 2026
dc403a4
fix: pass close reason through to pool memory so low yield cooldown t…
yunus-0x Mar 26, 2026
c9b0054
fix: use per-position PnL API data in getMyPositions instead of portf…
yunus-0x Mar 26, 2026
13c2ac3
feat: add minTokenAgeHours / maxTokenAgeHours screening filter
yunus-0x Mar 26, 2026
a28fff2
fix: push token age filter to API as base_token_created_at instead of…
yunus-0x Mar 26, 2026
4e00d0e
feat: intent-based tool routing for GENERAL agent
yunus-0x Mar 26, 2026
66d2494
fix: use volume_window instead of volume_24h in positions display
yunus-0x Mar 26, 2026
49d21f1
feat: add minTokenAgeHours/maxTokenAgeHours to reloadScreeningThresholds
yunus-0x Mar 26, 2026
751e5da
fix: add self_update to GENERAL agent intent routing
yunus-0x Mar 26, 2026
4d4cdb3
fix: strip model special tokens from tool names
yunus-0x Mar 26, 2026
ed27e92
fix: lock deploy_position after first attempt regardless of success
yunus-0x Mar 27, 2026
6c4d48b
fix: poller now triggers management for stop loss, OOR, and low yield
yunus-0x Mar 27, 2026
6eae81b
fix: skip low yield check on fresh positions
yunus-0x Mar 27, 2026
e21d3a4
fix: separate minAgeBeforeYieldCheck from outOfRangeWaitMinutes
yunus-0x Mar 27, 2026
b221091
feat: deployer blocklist — hard filter before LLM sees pools
yunus-0x Mar 28, 2026
ec5704e
fix: repair malformed tool argument JSON from model output
yunus-0x Mar 28, 2026
87d0849
fix: repair tool call JSON in message history before API re-submission
yunus-0x Mar 28, 2026
9e7c18c
fix: prevent GENERAL agent from hallucinating tool results
yunus-0x Mar 29, 2026
c1f5205
feat: OKX cluster analysis + ATH data
yunus-0x Mar 29, 2026
fb79d67
feat: OKX advanced-info + cluster/list for token analysis
yunus-0x Mar 29, 2026
4ba03e3
feat: wire OKX smart money + KOL to get_token_info and screening
yunus-0x Mar 29, 2026
76fcea4
feat: athFilterPct screening config — filter by distance from ATH
yunus-0x Mar 29, 2026
38687e4
fix: dex_boost/dex_screener_paid tags, fix dev_sold_all interpretatio…
yunus-0x Mar 29, 2026
64df74a
remove volume_24h and price_change_24h from getPriceInfo
yunus-0x Mar 29, 2026
6f8ae46
fix: split maxBundlersPct into maxBundlePct (OKX) and maxBotHoldersPc…
yunus-0x Mar 29, 2026
649d11c
feat: add OKX fields to screening candidateBlocks for LLM
yunus-0x Mar 29, 2026
e8b5b15
fix: strip <think> reasoning blocks before sending to Telegram
yunus-0x Mar 29, 2026
3f80604
feat: drop OKX API key requirement — use public Ok-Access-Client-type…
yunus-0x Mar 29, 2026
bc340d2
fix: restore missing closing brace in getTopCandidates after OKX guar…
yunus-0x Mar 29, 2026
f92de91
feat: add multi-provider LLM selection to setup wizard
yunus-0x Mar 30, 2026
13a5635
fix: wire all missing tools to GENERAL agent intent routing
yunus-0x Mar 30, 2026
03387fa
fix: smartwallet intent catches 'analyze pool' / 'check pool' patterns
yunus-0x Mar 30, 2026
f83420b
fix: wire solMode to actual SOL API fields throughout
yunus-0x Mar 31, 2026
0cab1bc
feat: wash trading hard filter + Darwinian signal weighting
yunus-0x Apr 1, 2026
cb3b9a0
fix: wire OKX risk flags and refresh example config
yunus-0x Apr 1, 2026
65e7a14
feat: expand deployment analysis report
yunus-0x Apr 1, 2026
c1d98e2
fix: surface OKX rugpull and wash flags to screener
yunus-0x Apr 1, 2026
789b51c
fix: close empty positions safely
yunus-0x Apr 2, 2026
c538448
refactor: hard-filter Jupiter bot holders instead of OKX bundle
yunus-0x Apr 2, 2026
4305848
fix: verify closes before recording pnl
yunus-0x Apr 2, 2026
5005dd8
fix: separate claim and close tx reporting
yunus-0x Apr 2, 2026
d658e30
fix: force close empty positions
yunus-0x Apr 2, 2026
650c295
fix: detect DLMM position liquidity correctly
yunus-0x Apr 2, 2026
260093c
fix: keep lesson pnl accounting in usd
yunus-0x Apr 2, 2026
aea7c58
fix: route top lpers requests correctly
yunus-0x Apr 2, 2026
1e4dba5
fix: preserve top lper wallet addresses
yunus-0x Apr 2, 2026
852a4a1
fix: enforce real deploy tool calls in telegram
yunus-0x Apr 2, 2026
163ac9f
fix: reject no-tool chat hallucinations
yunus-0x Apr 2, 2026
49dc696
fix: narrow interactive tool requirement
yunus-0x Apr 2, 2026
0f2ca79
feat: wire Meteora launchpad screening filters
yunus-0x Apr 2, 2026
b12074a
feat: stream live telegram progress
yunus-0x Apr 3, 2026
23dab93
fix: stop telegram typing on skipped cycles
yunus-0x Apr 3, 2026
eca8d57
fix: start screening live message after prechecks
yunus-0x Apr 3, 2026
037c0c1
refactor: simplify screening telegram report
yunus-0x Apr 3, 2026
44f3091
fix: clear screening busy on skipped prechecks
yunus-0x Apr 3, 2026
2ace3bb
feat: support authenticated okx requests
yunus-0x Apr 3, 2026
a9e8bf8
feat: add shortlist-based pvp rival guard
yunus-0x Apr 3, 2026
29f5eb7
feat: add optional hard pvp filter
yunus-0x Apr 3, 2026
4270dc9
fix: preserve okx risk flags when auth endpoints fail
yunus-0x Apr 3, 2026
b66b603
fix: use pnl api for open-position accounting
yunus-0x Apr 4, 2026
f880999
fix: harden telegram and tool execution paths
yunus-0x Apr 4, 2026
bf2e515
feat: cooldown repeated oor closes
yunus-0x Apr 4, 2026
0d4f9cd
fix: fall back when provider rejects system role
yunus-0x Apr 4, 2026
4618905
fix: bypass balance guards in dry run
yunus-0x Apr 4, 2026
349f447
fix: ignore startup sol threshold in dry run
yunus-0x Apr 4, 2026
9aacfa1
fix: fall back when provider rejects required tool choice
yunus-0x Apr 4, 2026
b562096
fix: allow updating oor cooldown config
yunus-0x Apr 4, 2026
8d4d97d
fix: confirm trailing peaks with 15s recheck
yunus-0x Apr 4, 2026
2e38dc2
fix: ignore suspicious open pnl ticks
yunus-0x Apr 4, 2026
515faaa
fix: add adjusted lp win rate and skip absurd closed pnl
yunus-0x Apr 5, 2026
e2d7cd3
fix: confirm trailing drops with 15s recheck
yunus-0x Apr 5, 2026
6655b71
fix: enable telegram polling in non-tty mode
yunus-0x Apr 5, 2026
6966bc8
feat: use lpagent for live position pnl when available
yunus-0x Apr 5, 2026
02fc965
fix: show filtered candidate examples in screening
yunus-0x Apr 6, 2026
e80a95c
fix: show earlier screening filter reasons
yunus-0x Apr 6, 2026
af52813
feat: add hivemind onboarding and shared sync
yunus-0x Apr 7, 2026
bc5417d
chore: refresh setup presets
yunus-0x Apr 7, 2026
7dcc27d
fix: migrate swaps to jupiter v2 and improve hive lessons
yunus-0x Apr 7, 2026
6b8f06e
Resolve manual pool names on close
yunus-0x Apr 7, 2026
15e227a
feat: add telegram control commands and hivemind pull modes
yunus-0x Apr 7, 2026
d67f00d
feat: add discord signal screening and sdk range reports
yunus-0x Apr 8, 2026
4959d10
fix: trigger management for deterministic poll exits
yunus-0x Apr 8, 2026
7eb4999
feat: add shared decision log for explanations
yunus-0x Apr 8, 2026
2f2cee4
feat: route LPAgent study and relay through Agent Meridian
yunus-0x Apr 9, 2026
36c200d
Delete scripts/test-lpagent-zap.mjs
yunus-0x Apr 9, 2026
bc873bb
fix: add fallback to Meteora path when Agent Meridian relay fails
yunus-0x Apr 9, 2026
7847169
chore: ignore docs/ directory
yunus-0x Apr 9, 2026
eacbe4b
feat: add server-backed chart indicator confirmations
yunus-0x Apr 9, 2026
3b0479e
fix: normalize relay sol values and expand indicator presets
yunus-0x Apr 10, 2026
3d12677
fix: stop indicators blocking exits
yunus-0x Apr 17, 2026
596a587
feat: add jupiter ultra referral config
yunus-0x Apr 17, 2026
c4cda54
fix: add agent meridian public defaults to experimental
yunus-0x Apr 17, 2026
578ba50
feat: route okx enrichment through agent meridian
yunus-0x Apr 17, 2026
b98e0a1
fix: retry open position relay checks
yunus-0x Apr 18, 2026
d8c21b4
feat: add telegram settings menu
yunus-0x Apr 19, 2026
a2696b1
fix: retry aborted open position relay calls
yunus-0x Apr 19, 2026
b96061c
feat: guard repeat deploy costs
yunus-0x Apr 20, 2026
43423ad
feat: GMGN token-first screening pipeline
yunus-0x Apr 20, 2026
b6a1506
feat: add dump KOL detection with threshold-based score penalty
yunus-0x Apr 20, 2026
ebc33f5
feat: replace +/- step buttons with input field on GMGN settings page
yunus-0x Apr 20, 2026
d048254
feat: replace all stepButtons with inputButton across all settings pages
yunus-0x Apr 20, 2026
a178da1
fix: inputButton truncating integer values (1000 → 1, 30 → 3)
yunus-0x Apr 20, 2026
f9010d3
feat: add Strategy settings page with bins/deploy config
yunus-0x Apr 20, 2026
d9afbf0
fix: remove duplicate strategy/bins buttons from Screen page
yunus-0x Apr 20, 2026
24656e8
fix: surface getTopCandidates errors instead of silent null
yunus-0x Apr 21, 2026
b03bab6
fix: increase GMGN rate limit delays to prevent IP ban
yunus-0x Apr 21, 2026
dc96bda
fix: force IPv4 for GMGN API requests
yunus-0x Apr 21, 2026
a6ac05b
fix: use dns.setDefaultResultOrder instead of undici for IPv4 forcing
yunus-0x Apr 21, 2026
84a9abd
feat: show S2+ filter reasons in every GMGN screening report
yunus-0x Apr 21, 2026
0c63e16
feat: add KOL Telegram menu page + fix GMGN screening bugs
yunus-0x Apr 21, 2026
d28a8ef
fix: restore GMGN page (was accidentally deleted) + add volume/maxBun…
yunus-0x Apr 21, 2026
ecd11ac
fix: restore strategy page, fix input routing for screen/kol/strategy…
yunus-0x Apr 21, 2026
a4db411
fix: flatten Telegram screen and KOL menu rows
yunus-0x Apr 21, 2026
954065f
fix: remove relay zap-out quote preflight
yunus-0x Apr 23, 2026
d342b7c
fix: harden env and relay signing
yunus-0x Apr 25, 2026
73d366c
fix: enforce screening thresholds before deploy
yunus-0x Apr 29, 2026
2e76b25
docs: add Meridian socials and agent harness
yunus-0x May 3, 2026
220255a
docs: correct HiveMind README details
yunus-0x May 4, 2026
99fb060
Guard DLMM deploy range and screening
yunus-0x May 6, 2026
bc17c45
Use 30m volatility for Meteora screening
yunus-0x May 7, 2026
ab9bff1
Preserve 30m volatility precision
yunus-0x May 7, 2026
8f9a4f1
Use screening timeframe for longer volatility windows
yunus-0x May 7, 2026
171c917
Fix PM2 restart handling
yunus-0x May 8, 2026
7f52a4d
Harden graceful shutdown under PM2
yunus-0x May 8, 2026
00a9b7f
Recognize PM2 entrypoint path
yunus-0x May 8, 2026
71be9bc
Enrich Discord signal launchpads before filtering
yunus-0x May 9, 2026
016f239
Move relay position enrichment into bot
yunus-0x May 13, 2026
7642e2c
fix: respect sol pnl and darwin snapshots
yunus-0x May 15, 2026
b6e99ce
fix: resolve false volume=0 rejections in screening
yunus-0x May 24, 2026
5da70ba
feat: add LP position simulator (Spot/Curve/Bid-Ask)
yunus-0x May 24, 2026
ed0fdab
feat: rebuild simulator as live paper position tracker
yunus-0x May 24, 2026
872ecc3
fix: price scale normalization and IL calculation in paper positions
yunus-0x May 24, 2026
29e54a0
Add autonomous paper-trading bridge + validation gate
zenginamca00 Jun 1, 2026
d690903
Move paper bridge to executor.js so all deploy paths open paper posit…
zenginamca00 Jun 1, 2026
5dee9f8
Fix REPL commands using dead default model; show real model in startu…
zenginamca00 Jun 1, 2026
6c3db3a
Show live open-position detail in paper-stats (PnL, fees, IL, range, …
zenginamca00 Jun 1, 2026
1e93c21
Gitignore paper-positions.json (runtime paper-trade state)
zenginamca00 Jun 1, 2026
b7b8bf2
Add stale dead-money cull to paper exits
zenginamca00 Jun 2, 2026
31bb081
Safe fixes: SOL-quote filter, base-token dedup, eligible count
zenginamca00 Jun 2, 2026
c328afd
Switch to curve strategy centered at current price
zenginamca00 Jun 2, 2026
d625059
Honest net learning, rich close report, interactive position cards, p…
zenginamca00 Jun 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ LPAGENT_API_KEY=your_lpagent_api_key_here
# ── Telegram Notifications (optional) ─────────────────────────────────────────
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=
TELEGRAM_ALLOWED_USER_IDS=

# ── Dangerous admin actions (disabled by default) ─────────────────────────────
ALLOW_SELF_UPDATE=false

# ── Misc ───────────────────────────────────────────────────────────────────────
DRY_RUN=false
Expand Down
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ node_modules/
.env
.env.*
!.env.example
.envrypt

# User config (contains RPC URL, wallet key, API keys)
user-config.json
gmgn-config.json

# Runtime state (position tracking, lessons — user-specific)
state.json
Expand All @@ -16,6 +18,10 @@ smart-wallets.json
pool-memory.json
token-blacklist.json
strategy-library.json
decision-log.json
hivemind-cache.json
signal-weights.json
paper-positions.json

# Logs
logs/
Expand All @@ -25,3 +31,7 @@ logs/

# Dev context
context.md
docs/

# Test files
test-*.js
16 changes: 10 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,22 +112,26 @@ Before `deploy_position` executes:
- Position count must be below `maxPositions` (force-fresh scan, no cache)
- No duplicate pool allowed (same pool_address)
- No duplicate base token allowed (same base_mint in another pool)
- If `amount_x > 0`: strip `amount_y` and `amount_sol` (tokenX-only deploy — no SOL needed)
- SOL balance must cover `amount_y + gasReserve` (skipped for tokenX-only)
- Deploy amount must include positive SOL (`amount_y` or `amount_sol`)
- Range width must be at least the configured safe bins floor (`minBinsBelow`, never below 35)
- Single-side SOL deploys must keep `bins_above=0`
- SOL balance must cover `amount_y + gasReserve`
- `blockedLaunchpads` enforced in `getTopCandidates()` before LLM sees candidates

---

## bins_below Calculation (SCREENER)

Linear formula based on pool volatility (set in screener prompt, `index.js`):
Linear formula based on pool volatility (set in screener prompt, `index.js`). The lower/upper bounds are configurable, with a hard safety floor of 35 bins:

```
bins_below = round(35 + (volatility / 5) * 34), clamped to [35, 69]
bins_below = round(minBinsBelow + (volatility / 5) * (maxBinsBelow - minBinsBelow))
clamped to [minBinsBelow, maxBinsBelow]
```

- Low volatility (0) → 35 bins
- High volatility (5+) → 69 bins
- Volatility must be finite and > 0; zero/missing volatility is treated as an unusable feed
- Low valid volatility → minBinsBelow
- High volatility (5+) → maxBinsBelow
- Any value in between is valid (continuous, not tiered)

---
Expand Down
90 changes: 90 additions & 0 deletions FINDINGS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Meridian — Findings & Issues (Draft)

_Paper validation run on VPS (`simulator-paper` branch, DRY_RUN). Compiled 2026-06-02._
_Goal: document issues found while paper-trading so they can be fixed/tested with data, not guesses._

---

## Current data snapshot (evidence)

```
Sample: 5 closed / 2 open — Win/Loss: 0 / 5
Net PnL: -$1.17 · Fees: $0.08 · Avg L: -0.83% · Worst: -1.22%
Exit breakdown: OOR 3 (avg -0.89%) · STALE 2 (avg -0.72%)
Open: GACHA-SOL (in-range 0%, 90m) · GACHA-USDC (in-range 0%, 51m)
```

**Headline:** every position so far has **in-range ~0–9% and ~$0 fees** — including clean/mature pools (three-SOL $3M mcap/182 SOL fees, GACHA 14% bots/91 organic). Losses are small & controlled (exit rules work), but **zero fee capture**.

---

## Issues

| # | Severity | Issue | Status |
|---|---|---|---|
| 1 | 🔴 High | Single-sided bid_ask downside → in-range ~0% → $0 fees (root cause of all losses) | Open — needs decision |
| 2 | 🔴 High | Screening picks non-SOL-quote pools (e.g. GACHA-USDC); deploy assumes SOL | Must-fix before LIVE |
| 3 | 🟡 Med | Strategy locked to `bid_ask` (curve/spot blocked by prompt + executor) | Open |
| 4 | 🟡 Med | Bin step screened 80–125; meme guides recommend 250–400 → fast OOR | Open |
| 5 | 🟡 Med | Thin candidate funnel on `meteora` source (no GMGN key) | Open |
| 6 | 🟡 Med | Paper bridge dedup is pool-level only (held GACHA-SOL + GACHA-USDC = 2x same base) | Open |
| 7 | 🟡 Low | Race condition: tickPaperPositions (async) vs bridge openPaperPosition can drop a trade (~1%) | Open |
| 8 | 🟢 Cosmetic | Duplicate "Deployed" Telegram notifs + report≠paper when bridge skips | Open |
| 9 | 🟢 Cosmetic | `editMessageText 400: message not modified` (live progress edit) | Open |
| 10 | 🟢 Cosmetic | "undefined eligible from N screened" (simulator branch lacks main's fix) | Open |
| 11 | ✅ Resolved | Default model `openrouter/healer-alpha` retired (404) | Fixed → deepseek-v4-flash |

---

## Detail

### 🔴 #1 — Structural: single-sided bid_ask downside earns ~0 fees
- **What:** Deploy = single-sided SOL, bins below only (`bins_above=0`). Position sits at the TOP edge of its range (upper bound = active bin at deploy). Any upward price move → instantly OOR-up → $0 fees. Only earns when price FALLS into the bins.
- **Evidence:** 7 positions, all in-range 0–9%, ~$0 fees — even clean/mature pools. Not token-dependent → structural.
- **Impact:** No fee capture. Strategy behaves as "DCA buy-the-dip", NOT fee-farming. Edge depends on tokens dipping-then-recovering; current tokens pump up / chop.
- **Proposed (test later):** allow centered shapes (curve/spot, or `bins_above > 0` two-sided) → stay in-range → earn fees. Community proof: Kinji `curve` +8.43%.

### 🔴 #2 — Non-SOL-quote pools selected
- **What:** `screening.js` checks quote organic/warnings but has NO "quote == SOL" filter. So USDC-quote pools (GACHA-USDC) pass. Deploy uses `amount_y` = quote token; for a USDC pool that means USDC, not SOL — but logic/report assume SOL.
- **Impact:** Paper = harmless (bridge uses USD). **LIVE = real bug** (deploys wrong token / wallet lacks USDC).
- **Proposed:** add SOL-quote-only filter to screening before going live.

### 🟡 #3 — Strategy locked to bid_ask
- Prompt: "strategy = bid_ask, always use this, never change." Executor enforces single-side SOL + `bins_above=0`. Cannot use curve/spot without code/config changes.

### 🟡 #4 — Bin step too narrow for memes
- Config screens `minBinStep 80 / maxBinStep 125`. Practitioner guides: 250–400 for volatile memes (wider price coverage → stays in range). Narrow bins → fast OOR.

### 🟡 #5 — Thin funnel (meteora source)
- On `screeningSource: meteora` + Jupiter bot metric (`maxBotHoldersPct 30`). Many trending pools are botty (Magpie 42%) → few candidates. Community uses `screeningSource: gmgn` (different universe + bot metric) for more flow — requires GMGN_API_KEY (not set).

### 🟡 #6 — Bridge dedup is pool-level
- Bridge skips duplicate POOL, but not duplicate BASE TOKEN. Held GACHA-SOL + GACHA-USDC simultaneously (both base = GACHA). Live executor has base-mint dedup; paper bridge doesn't.

### 🟡 #7 — Race condition (low prob)
- `tickPaperPositions` holds stale `state` across `await fetchNewCandles`; if bridge `openPaperPosition` saves during that window, tick's save can overwrite it → trade dropped (~1%/deploy). `evaluatePaperExits` is sync (safe).

### 🟢 #8–10 — Cosmetic
- Dup deploy notifs; editMessageText 400; "undefined eligible" label. None affect behavior/data.

---

## Branch / config notes (confirmed)

- **GMGN screening** (`screeningSource: meteora|gmgn`, `gmgn-config.json`, `tools/gmgn.js`) exists on **experimental + simulator** branches, NOT on `main`. (Meridian Helper bot answers from `main` context → says "no GMGN" — correct for main only.)
- Experimental extras: `repeatDeployCooldown`, `emergencyPriceDropPct`, `gmgnRequireKol`.
- Agent names: "Hunter Alpha" (screener) / "Healer Alpha" (manager) = also the retired OpenRouter stealth-model aliases.

## Custom additions on `simulator-paper` (for record)
- Paper bridge: dry-run deploy → `openPaperPosition` (executor.js) — covers cron/auto/manual
- `evaluatePaperExits`: SL / TP / trailing / OOR / **STALE dead-money** cull
- `paper-stats.mjs`: Charonica-style validation gate + live open-position view
- Provider routing (pin DeepSeek), Telegram topic (thread 1398)

---

## Open questions / next steps
1. After ~15–20 closed trades: if in-range stays ~0% → confirm structural → decide on curve/spot or two-sided.
2. Get GMGN_API_KEY → A/B test `gmgn` vs `meteora` source.
3. Add SOL-quote filter **before any live trading**.
4. Decide: keep Meridian's "DCA buy-the-dip" thesis, or reshape toward fee-farming (centered ranges).
111 changes: 79 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

**Autonomous Meteora DLMM liquidity management agent for Solana, powered by LLMs.**

**Links:** [Website](https://agentmeridian.xyz) | [Telegram](https://t.me/agentmeridian) | [X](https://x.com/meridian_agent)

---

## What it does
Expand All @@ -26,6 +28,12 @@ Meridian runs a **ReAct agent loop** — each cycle the LLM reasons over live da

A third **health check** runs hourly to summarize portfolio state.

### Agent harness

Meridian's agent harness is the runtime wrapper around every autonomous cycle. It gives both **main** and **experimental** agents the same control loop: load live state, inject relevant memory, expose only role-appropriate tools, execute tool calls, and return a readable cycle report.

The harness also keeps a structured decision log in `decision-log.json` for deployments, closes, skips, and no-deploy outcomes. Each entry records the actor, pool or position, summary, reason, key risks, metrics, and rejected alternatives. Recent decisions are injected back into the system prompt and are available through `get_recent_decisions`, so the agent can answer "why did you deploy?", "why did you close?", or "why did you skip?" without guessing after the fact.

**Data sources used by the agents:**
- `@meteora-ag/dlmm` SDK — on-chain position data, active bin, deploy/close transactions
- Meteora DLMM PnL API — position yield, fee accrual, PnL
Expand Down Expand Up @@ -73,6 +81,16 @@ DRY_RUN=true # set false for live trading

> **RPC**: defaults to `https://pump.helius-rpc.com` (no key needed). Override with `RPC_URL=` in `.env`.

Optional encrypted `.env` flow:

```bash
cp .env .env.raw
printf "replace-with-a-long-local-key\n" > .envrypt
npm run env:encrypt
```

Meridian loads envrypt-style encrypted values automatically. Keep `.env.raw` and `.envrypt` local; both are gitignored.

**4. Copy the example config**

```bash
Expand All @@ -88,6 +106,32 @@ npm start # live mode

On startup Meridian fetches your wallet balance, open positions, and the top pool candidates, then begins autonomous cycles immediately.

### Run with PM2

PM2 is supported and is the recommended way to keep Telegram control online on a VPS:

```bash
npm install
npm run pm2:start
pm2 save
```

To update an existing PM2 install:

```bash
git pull
npm install
npm run pm2:restart
```

If the process restarts repeatedly after an update, inspect the app error first:

```bash
npm run pm2:logs
```

Most post-update PM2 crashes are app startup errors, commonly from skipping `npm install` after `package-lock.json` changed, starting PM2 from the wrong directory, or missing `.env` / `user-config.json` values. Avoid `nohup`; it runs outside PM2 and can leave Telegram polling in a duplicate unmanaged process.

---

## Config reference
Expand All @@ -101,7 +145,7 @@ All fields are optional — defaults shown. Edit `user-config.json`.
| `dryRun` | `true` | Simulate all transactions without submitting |
| `deployAmountSol` | `0.5` | SOL to deploy per new position |
| `maxPositions` | `3` | Maximum concurrent open positions |
| `minSolToOpen` | `0.07` | Minimum wallet SOL balance before opening a new position |
| `minSolToOpen` | `0.55` | Minimum wallet SOL balance before opening a new position |
| `managementIntervalMin` | `10` | How often the management agent runs (minutes) |
| `screeningIntervalMin` | `30` | How often the screening agent runs (minutes) |
| `managementModel` | `openrouter/healer-alpha` | LLM model for position management |
Expand All @@ -114,7 +158,7 @@ All fields are optional — defaults shown. Edit `user-config.json`.
| `minHolders` | `500` | Minimum token holder count |
| `timeframe` | `5m` | Candle timeframe used in screening |
| `category` | `trending` | Pool category filter for screening |
| `takeProfitFeePct` | `5` | Close position when unclaimed fees reach this % of deployed capital |
| `takeProfitPct` | `5` | Close position when PnL reaches this % threshold |
| `outOfRangeWaitMinutes` | `30` | Minutes a position can be out of range before alerting / acting |

---
Expand Down Expand Up @@ -152,9 +196,20 @@ Free-form chat persists session history (last 10 exchanges), so you can have a c

1. Create a bot via [@BotFather](https://t.me/BotFather) and copy the token
2. Add `TELEGRAM_BOT_TOKEN=<token>` to your `.env`
3. Start the agent, then send **any message** to your bot
3. Set the exact Telegram chat and allowed controller user IDs in `.env`

Meridian no longer auto-registers the first chat for safety. You must set:

```env
TELEGRAM_BOT_TOKEN=<token>
TELEGRAM_CHAT_ID=<target chat id>
TELEGRAM_ALLOWED_USER_IDS=<comma-separated Telegram user ids allowed to control the bot>
```

On first message, the agent auto-registers your chat ID and begins sending notifications. No manual chat ID configuration needed.
Security notes:
- If `TELEGRAM_CHAT_ID` is not set, inbound Telegram control is ignored.
- If the target chat is a group/supergroup and `TELEGRAM_ALLOWED_USER_IDS` is empty, inbound control is ignored.
- Notifications still go to the configured chat, but command/control is limited to the allowed user IDs.

**Notifications sent:**
- After every management cycle: full agent report (reasoning + decisions)
Expand All @@ -163,7 +218,7 @@ On first message, the agent auto-registers your chat ID and begins sending notif
- On deploy: pair, amount, position address, tx hash
- On close: pair and PnL

You can also chat with the agent via Telegram using the same free-form interface as the REPL: `"check wallet 7tB8..."`, `"who are the top LPers in pool ABC..."`, `"close all positions"`, etc.
You can also chat with the agent via Telegram using the same free-form interface as the REPL: `"check wallet 7tB8..."`, `"who are the top LPers in pool ABC..."`, `"close all positions"`, etc. Only explicitly allowed Telegram user IDs can issue commands.

---

Expand All @@ -185,53 +240,45 @@ Use `/thresholds` to see current values alongside performance stats.

---

## Hive Mind (optional)
## HiveMind

Meridian includes an **opt-in** collective intelligence system called **Hive Mind**. When enabled, your agent anonymously shares what it learns (lessons, deploy outcomes, screening thresholds) with other meridian agents and receives crowd wisdom in return.
Meridian includes a collective intelligence layer called **HiveMind**. By default it uses Agent Meridian at `https://api.agentmeridian.xyz` with the built-in public key, so agents can register, pull shared lessons/presets, and push learning events without a separate registration flow.

**What you get:**
- Pool consensus from other agents — "8 agents deployed here, 72% win rate"
- Strategy rankings — which strategies actually work across all agents
- Pattern consensus — what works at different volatility levels
- Threshold medians — what screening settings other agents have evolved to
- Shared lessons from other Meridian agents
- Strategy presets and crowd performance context
- Role-aware lessons injected into future screener/manager prompts when `hiveMindPullMode` is `auto`

**What you share:**
- Lessons from `lessons.json`
- Deploy outcomes from `pool-memory.json` (pool address, strategy, PnL, hold time)
- Screening thresholds from `user-config.json`
- **NO wallet addresses, private keys, or SOL balances are ever sent**
- Closed-position performance events: pool, pool name, base mint, strategy, close reason, PnL, fees, and hold time
- Agent heartbeat metadata: agent ID, version, timestamp, and basic capability flags
- **Private keys and wallet balances are never sent**

**Impact:** 1 non-blocking API call per screening cycle (~200ms), 1 fire-and-forget POST on position close. If the hive is down, your agent doesn't notice.
HiveMind failures are non-blocking. If Agent Meridian is unavailable, the agent logs a warning and keeps running.

### Setup

**1. Get the registration token** from the private Telegram discussion.
No manual HiveMind registration command is required for the shared Agent Meridian setup. `agentId` is generated automatically on startup if it is missing.

**2. Register your agent**
To use a private HiveMind API key, check the Telegram announcement channel and set it as `hiveMindApiKey`.

```bash
node -e "import('./hive-mind.js').then(m => m.register('https://meridian-hive-api-production.up.railway.app', 'YOUR_TOKEN'))"
```

Replace `YOUR_TOKEN` with the registration token from Telegram.

This automatically saves your credentials to `user-config.json`. **Save the API key printed in the terminal** — it will not be shown again.

**3. Done.** No restart needed. Your agent will sync on every position close and query the hive during screening.
Relevant config fields:

### Disable

Clear both fields in `user-config.json`:
```json
{
"agentId": "",
"hiveMindUrl": "",
"hiveMindApiKey": ""
"hiveMindApiKey": "",
"hiveMindPullMode": "auto"
}
```

### Self-hosting
Blank `hiveMindUrl` and `hiveMindApiKey` values intentionally fall back to the Agent Meridian defaults. Set `hiveMindPullMode` to `manual` if you do not want shared lessons and presets pulled automatically.

### Disable

You can run your own hive server instead of using the public one. See [meridian-hive](https://github.com/fciaf420/meridian-hive) for the server source code.
There is currently no empty-string disable path for HiveMind; blank values fall back to the built-in Agent Meridian defaults. A true off switch should be implemented as an explicit config flag before documenting HiveMind as disabled by clearing fields.

---

Expand Down
Loading