gmgn-holder-analysis

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
BEFORE RUNNING ANY COMMAND: Run
gmgn-cli config --check
. If exit code is 0, proceed normally. If exit code is 1, run
gmgn-cli config
and show output, then apply the key with
gmgn-cli config --apply <KEY>
. If unknown option, tell user to run
npm install -g gmgn-cli
.
IMPORTANT: Always use
gmgn-cli
commands. Do NOT use curl, WebFetch, or visit gmgn.ai.
When the user asks to analyze holders for a token, extract
--chain
and
--address
from their message, then run the analysis script below. Also detect the user's language: set
LANG
to
'zh'
if the user wrote in Chinese,
'en'
if in English (default
'zh'
).
运行任何命令前:执行
gmgn-cli config --check
。如果退出码为0,正常继续;如果退出码为1,执行
gmgn-cli config
并展示输出,然后使用
gmgn-cli config --apply <KEY>
配置密钥。如果遇到未知选项,告知用户执行
npm install -g gmgn-cli
重要提示:始终使用
gmgn-cli
命令,禁止使用curl、WebFetch或访问gmgn.ai。
当用户要求分析某Token的持仓情况时,从用户消息中提取
--chain
--address
参数,然后运行下方的分析脚本。同时检测用户语言:如果用户使用中文,将
LANG
设置为
'zh'
;如果使用英文,设置为
'en'
(默认值为
'zh'
)。

Analysis Script

分析脚本

Run this Python script inline, replacing
<FILL_IN_TOKEN_ADDRESS>
,
<FILL_IN_CHAIN>
, and
<FILL_IN_LANG>
with the actual values:
python
python3 << 'PYEOF'
import json, subprocess, time
from collections import defaultdict
from concurrent.futures import ThreadPoolExecutor

TOKEN_ADDR = "<FILL_IN_TOKEN_ADDRESS>"
CHAIN      = "<FILL_IN_CHAIN>"
LANG       = "<FILL_IN_LANG>"   # 'zh' or 'en'
WINDOW     = 1800
now_ts     = int(time.time())

ZH = (LANG == 'zh')
def _(zh, en): return zh if ZH else en

def run_cli(args, timeout=30):
    r = subprocess.run(['gmgn-cli'] + args + ['--raw'],
                       capture_output=True, text=True, timeout=timeout)
    if r.returncode != 0:
        raise RuntimeError(r.stderr)
    return json.loads(r.stdout)
直接运行以下Python脚本,将
<FILL_IN_TOKEN_ADDRESS>
<FILL_IN_CHAIN>
<FILL_IN_LANG>
替换为实际值:
python
python3 << 'PYEOF'
import json, subprocess, time
from collections import defaultdict
from concurrent.futures import ThreadPoolExecutor

TOKEN_ADDR = "<FILL_IN_TOKEN_ADDRESS>"
CHAIN      = "<FILL_IN_CHAIN>"
LANG       = "<FILL_IN_LANG>"   # 'zh' or 'en'
WINDOW     = 1800
now_ts     = int(time.time())

ZH = (LANG == 'zh')
def _(zh, en): return zh if ZH else en

def run_cli(args, timeout=30):
    r = subprocess.run(['gmgn-cli'] + args + ['--raw'],
                       capture_output=True, text=True, timeout=timeout)
    if r.returncode != 0:
        raise RuntimeError(r.stderr)
    return json.loads(r.stdout)

Fetch holders and devs in parallel, then created-tokens after extracting creator

并行获取持仓者和开发者信息,提取创建者后获取其发行过的Token

with ThreadPoolExecutor(max_workers=2) as ex: f_holders = ex.submit(run_cli, ['token', 'holders', '--chain', CHAIN, '--address', TOKEN_ADDR, '--limit', '100']) f_devs = ex.submit(run_cli, ['token', 'holders', '--chain', CHAIN, '--address', TOKEN_ADDR, '--tag', 'dev', '--limit', '20'])
holders = f_holders.result()['list'] devs = f_devs.result()['list']
_creator_tmp = next((d for d in devs if 'creator' in (d.get('maker_token_tags') or [])), None) created_data = None if _creator_tmp: try: created_data = run_cli(['portfolio', 'created-tokens', '--chain', CHAIN, '--wallet', _creator_tmp['address'], '--order-by', 'token_ath_mc', '--direction', 'desc']) except: pass
with ThreadPoolExecutor(max_workers=2) as ex: f_holders = ex.submit(run_cli, ['token', 'holders', '--chain', CHAIN, '--address', TOKEN_ADDR, '--limit', '100']) f_devs = ex.submit(run_cli, ['token', 'holders', '--chain', CHAIN, '--address', TOKEN_ADDR, '--tag', 'dev', '--limit', '20'])
holders = f_holders.result()['list'] devs = f_devs.result()['list']
_creator_tmp = next((d for d in devs if 'creator' in (d.get('maker_token_tags') or [])), None) created_data = None if _creator_tmp: try: created_data = run_cli(['portfolio', 'created-tokens', '--chain', CHAIN, '--wallet', _creator_tmp['address'], '--order-by', 'token_ath_mc', '--direction', 'desc']) except: pass

── Wallet classification ────────────────────────────────

── 钱包分类 ────────────────────────────────

addr_type: 0=normal, 1=burn, 2=DEX/pool

addr_type: 0=普通钱包, 1=销毁地址, 2=DEX/流动性池

normal = [h for h in holders if h.get('addr_type', 0) == 0] burn = [h for h in holders if h.get('addr_type', 0) == 1] dex = [h for h in holders if h.get('addr_type', 0) == 2]
normal = [h for h in holders if h.get('addr_type', 0) == 0] burn = [h for h in holders if h.get('addr_type', 0) == 1] dex = [h for h in holders if h.get('addr_type', 0) == 2]

── Helpers ──────────────────────────────────────────────

── 辅助函数 ──────────────────────────────────────────────

def pct(v): return v * 100 def usd(v): if v is None: return "$0" if abs(v) >= 1_000_000: return f"${v/1_000_000:.2f}M" if abs(v) >= 1_000: return f"${v/1_000:.1f}K" return f"${v:.0f}" def fmt_amt(v): if v >= 1_000_000: return f"{v/1_000_000:.1f}M" if v >= 1_000: return f"{v/1_000:.0f}K" return f"{v:.0f}" def age_label(entry_ts): secs = now_ts - entry_ts days = secs // 86400 hours = secs // 3600 if ZH: return f"{hours}小时前入场" if days == 0 else f"{days}天前入场" else: return f"{hours}h ago" if days == 0 else f"{days}d ago" def addr_short(addr): return f"{addr[:4]}...{addr[-4:]}"
def pct(v): return v * 100 def usd(v): if v is None: return "$0" if abs(v) >= 1_000_000: return f"${v/1_000_000:.2f}M" if abs(v) >= 1_000: return f"${v/1_000:.1f}K" return f"${v:.0f}" def fmt_amt(v): if v >= 1_000_000: return f"{v/1_000_000:.1f}M" if v >= 1_000: return f"{v/1_000:.0f}K" return f"{v:.0f}" def age_label(entry_ts): secs = now_ts - entry_ts days = secs // 86400 hours = secs // 3600 if ZH: return f"{hours}小时前入场" if days == 0 else f"{days}天前入场" else: return f"{hours}h ago" if days == 0 else f"{days}d ago" def addr_short(addr): return f"{addr[:4]}...{addr[-4:]}"

── Price / MC ───────────────────────────────────────────

── 价格 / 市值 ───────────────────────────────────────────

supply_list = [h['balance']/h['amount_percentage'] for h in normal if h.get('amount_percentage',0)>0 and h.get('balance',0)>0] total_supply = sorted(supply_list)[len(supply_list)//2] if supply_list else 1_000_000_000 price_list = [h['usd_value']/h['balance'] for h in normal if h.get('balance',0)>0 and h.get('usd_value',0)>0] cur_price = sorted(price_list)[len(price_list)//2] if price_list else 0 cur_mc = total_supply * cur_price
burn_pct = sum(h['amount_percentage'] for h in burn) dex_pct = sum(h['amount_percentage'] for h in dex) top10 = sum(h['amount_percentage'] for h in holders[:10]) top20 = sum(h['amount_percentage'] for h in holders[:20])
supply_list = [h['balance']/h['amount_percentage'] for h in normal if h.get('amount_percentage',0)>0 and h.get('balance',0)>0] total_supply = sorted(supply_list)[len(supply_list)//2] if supply_list else 1_000_000_000 price_list = [h['usd_value']/h['balance'] for h in normal if h.get('balance',0)>0 and h.get('usd_value',0)>0] cur_price = sorted(price_list)[len(price_list)//2] if price_list else 0 cur_mc = total_supply * cur_price
burn_pct = sum(h['amount_percentage'] for h in burn) dex_pct = sum(h['amount_percentage'] for h in dex) top10 = sum(h['amount_percentage'] for h in holders[:10]) top20 = sum(h['amount_percentage'] for h in holders[:20])

── Risk wallets ─────────────────────────────────────────

── 风险钱包 ─────────────────────────────────────────

maker_token_tags: bundler, rat_trader, sniper, whale, top_holder, transfer_in, dev_team, creator

maker_token_tags: bundler, rat_trader, sniper, whale, top_holder, transfer_in, dev_team, creator

tags: smart_degen, pump_smart, renowned, fresh_wallet, wash_trader, fomo, kol

tags: smart_degen, pump_smart, renowned, fresh_wallet, wash_trader, fomo, kol

airdrop = [h for h in normal if h.get('buy_tx_count_cur', 0)==0 and h.get('balance', 0)>0] bundlers = [h for h in normal if 'bundler' in (h.get('maker_token_tags') or [])] rats = [h for h in normal if 'rat_trader' in (h.get('maker_token_tags') or [])] snipers = [h for h in normal if 'sniper' in (h.get('maker_token_tags') or [])] fresh = [h for h in normal if 'fresh_wallet' in (h.get('tags') or [])] wash = [h for h in normal if 'wash_trader' in (h.get('tags') or [])] risk_all = set(h['address'] for g in [bundlers, rats, snipers, fresh, wash] for h in g) risk_pct = sum(h['amount_percentage'] for h in normal if h['address'] in risk_all)
airdrop_pct = sum(h['amount_percentage'] for h in airdrop) rats_pct = sum(h['amount_percentage'] for h in rats)
airdrop = [h for h in normal if h.get('buy_tx_count_cur', 0)==0 and h.get('balance', 0)>0] bundlers = [h for h in normal if 'bundler' in (h.get('maker_token_tags') or [])] rats = [h for h in normal if 'rat_trader' in (h.get('maker_token_tags') or [])] snipers = [h for h in normal if 'sniper' in (h.get('maker_token_tags') or [])] fresh = [h for h in normal if 'fresh_wallet' in (h.get('tags') or [])] wash = [h for h in normal if 'wash_trader' in (h.get('tags') or [])] risk_all = set(h['address'] for g in [bundlers, rats, snipers, fresh, wash] for h in g) risk_pct = sum(h['amount_percentage'] for h in normal if h['address'] in risk_all)
airdrop_pct = sum(h['amount_percentage'] for h in airdrop) rats_pct = sum(h['amount_percentage'] for h in rats)

── Healthy chip ratio ───────────────────────────────────

── 健康筹码比例 ───────────────────────────────────

normal_pct = sum(h['amount_percentage'] for h in normal) all_bad = set(h['address'] for h in airdrop) | risk_all bad_pct = sum(h['amount_percentage'] for h in normal if h['address'] in all_bad) healthy_pct = max(normal_pct - bad_pct, 0) healthy_ratio = (healthy_pct / normal_pct) if normal_pct > 0 else 0
normal_pct = sum(h['amount_percentage'] for h in normal) all_bad = set(h['address'] for h in airdrop) | risk_all bad_pct = sum(h['amount_percentage'] for h in normal if h['address'] in all_bad) healthy_pct = max(normal_pct - bad_pct, 0) healthy_ratio = (healthy_pct / normal_pct) if normal_pct > 0 else 0

── Related wallets ──────────────────────────────────────

── 关联钱包 ──────────────────────────────────────

from_map = defaultdict(list) for h in normal: fa = (h.get('native_transfer') or {}).get('from_address', '') if fa: from_map[fa].append(h) same_src_groups = sorted([(fa, ws) for fa, ws in from_map.items() if len(ws)>=2], key=lambda x: -len(x[1])) same_src_wallets = sum(len(ws) for __,ws in same_src_groups) same_src_pct = sum(h['amount_percentage'] for __,ws in same_src_groups for h in ws)
funded = [((h.get('native_transfer') or {}).get('timestamp',0), h) for h in normal if (h.get('native_transfer') or {}).get('timestamp',0)] bucket = defaultdict(list) for ts, h in funded: bucket[(ts//WINDOW)*WINDOW].append(h) win_groups = sorted([(k,v) for k,v in bucket.items() if len(v)>=2], key=lambda x: -len(x[1])) win_pct = sum(h['amount_percentage'] for __,v in win_groups for h in v)
related = set() for __,ws in same_src_groups: for h in ws: related.add(h['address']) for __,v in win_groups: for h in v: related.add(h['address']) related_pct = sum(h['amount_percentage'] for h in normal if h['address'] in related) related_usd = sum(h.get('usd_value',0) for h in normal if h['address'] in related)
from_map = defaultdict(list) for h in normal: fa = (h.get('native_transfer') or {}).get('from_address', '') if fa: from_map[fa].append(h) same_src_groups = sorted([(fa, ws) for fa, ws in from_map.items() if len(ws)>=2], key=lambda x: -len(x[1])) same_src_wallets = sum(len(ws) for __,ws in same_src_groups) same_src_pct = sum(h['amount_percentage'] for __,ws in same_src_groups for h in ws)
funded = [((h.get('native_transfer') or {}).get('timestamp',0), h) for h in normal if (h.get('native_transfer') or {}).get('timestamp',0)] bucket = defaultdict(list) for ts, h in funded: bucket[(ts//WINDOW)*WINDOW].append(h) win_groups = sorted([(k,v) for k,v in bucket.items() if len(v)>=2], key=lambda x: -len(x[1])) win_pct = sum(h['amount_percentage'] for __,v in win_groups for h in v)
related = set() for __,ws in same_src_groups: for h in ws: related.add(h['address']) for __,v in win_groups: for h in v: related.add(h['address']) related_pct = sum(h['amount_percentage'] for h in normal if h['address'] in related) related_usd = sum(h.get('usd_value',0) for h in normal if h['address'] in related)

── Quality signals ──────────────────────────────────────

── 优质信号 ──────────────────────────────────────

smart = [h for h in normal if any(t in (h.get('tags') or []) for t in ['smart_degen','pump_smart'])] kol = [h for h in normal if 'kol' in (h.get('tags') or []) or 'renowned' in (h.get('tags') or [])] whales = [h for h in normal if 'whale' in (h.get('maker_token_tags') or [])] diamond = [h for h in normal if h.get('sell_tx_count_cur',0)==0 and h.get('balance',0)>0] partial = [h for h in normal if 0<(h.get('sell_amount_percentage') or 0)<0.5] heavy_sell = [h for h in normal if (h.get('sell_amount_percentage') or 0)>=0.5]
smart_pct = sum(h['amount_percentage'] for h in smart) kol_pct = sum(h['amount_percentage'] for h in kol) whale_pct = sum(h['amount_percentage'] for h in whales) diamond_pct = sum(h['amount_percentage'] for h in diamond)
smart = [h for h in normal if any(t in (h.get('tags') or []) for t in ['smart_degen','pump_smart'])] kol = [h for h in normal if 'kol' in (h.get('tags') or []) or 'renowned' in (h.get('tags') or [])] whales = [h for h in normal if 'whale' in (h.get('maker_token_tags') or [])] diamond = [h for h in normal if h.get('sell_tx_count_cur',0)==0 and h.get('balance',0)>0] partial = [h for h in normal if 0<(h.get('sell_amount_percentage') or 0)<0.5] heavy_sell = [h for h in normal if (h.get('sell_amount_percentage') or 0)>=0.5]
smart_pct = sum(h['amount_percentage'] for h in smart) kol_pct = sum(h['amount_percentage'] for h in kol) whale_pct = sum(h['amount_percentage'] for h in whales) diamond_pct = sum(h['amount_percentage'] for h in diamond)

── Dev data ─────────────────────────────────────────────

── 开发者数据 ─────────────────────────────────────

top100_map = {h['address']: h for h in holders} creator = next((d for d in devs if 'creator' in (d.get('maker_token_tags') or [])), None) sub_devs = [d for d in devs if 'creator' not in (d.get('maker_token_tags') or [])] dev_realized = sum(d.get('realized_profit') or 0 for d in devs) dev_holding = [d for d in devs if (d.get('balance') or 0)>=1]
top100_map = {h['address']: h for h in holders} creator = next((d for d in devs if 'creator' in (d.get('maker_token_tags') or [])), None) sub_devs = [d for d in devs if 'creator' not in (d.get('maker_token_tags') or [])] dev_realized = sum(d.get('realized_profit') or 0 for d in devs) dev_holding = [d for d in devs if (d.get('balance') or 0)>=1]

── Holding metrics ──────────────────────────────────────

── 持仓指标 ──────────────────────────────────────

valid_starts = [h['start_holding_at'] for h in holders if (h.get('start_holding_at') or 0)>0] token_launch = min(valid_starts) if valid_starts else now_ts durations = [now_ts-h['start_holding_at'] for h in normal if (h.get('start_holding_at') or 0)>0 and now_ts>h['start_holding_at']] avg_hold_days = (sum(durations)/len(durations)/86400) if durations else 0
profit_w = [h for h in normal if (h.get('profit') or 0)>0] loss_w = [h for h in normal if (h.get('profit') or 0)<0] trapped = [h for h in normal if (h.get('unrealized_pnl') or 0)<-0.2 and h.get('balance',0)>0]
valid_starts = [h['start_holding_at'] for h in holders if (h.get('start_holding_at') or 0)>0] token_launch = min(valid_starts) if valid_starts else now_ts durations = [now_ts-h['start_holding_at'] for h in normal if (h.get('start_holding_at') or 0)>0 and now_ts>h['start_holding_at']] avg_hold_days = (sum(durations)/len(durations)/86400) if durations else 0
profit_w = [h for h in normal if (h.get('profit') or 0)>0] loss_w = [h for h in normal if (h.get('profit') or 0)<0] trapped = [h for h in normal if (h.get('unrealized_pnl') or 0)<-0.2 and h.get('balance',0)>0]

── Buying power ─────────────────────────────────────────

── 购买力分析 ─────────────────────────────────────────

SOL: native_balance in lamports (1e9); EVM: in wei (1e18)

SOL: native_balance 单位为lamports(1e9);EVM: 单位为wei(1e18)

NATIVE_PRICE = 160 if CHAIN == 'sol' else (700 if CHAIN == 'bsc' else 2500) NATIVE_DENOM = 1e9 if CHAIN == 'sol' else 1e18 def native_usd(h): return int(h.get('native_balance') or 0)/NATIVE_DENOM*NATIVE_PRICE zero_wallets = [h for h in normal if native_usd(h)==0] low_wallets = [h for h in normal if 0 < native_usd(h) <= 200] mid_wallets = [h for h in normal if 200 < native_usd(h) <= 1200] high_wallets = [h for h in normal if native_usd(h) > 1200] zero_pct_val = sum(h['amount_percentage'] for h in zero_wallets) low_pct_val = sum(h['amount_percentage'] for h in low_wallets) mid_pct_val = sum(h['amount_percentage'] for h in mid_wallets) high_pct_val = sum(h['amount_percentage'] for h in high_wallets) high_total = sum(native_usd(h) for h in high_wallets) total_buying_power = sum(native_usd(h) for h in normal)
NATIVE_PRICE = 160 if CHAIN == 'sol' else (700 if CHAIN == 'bsc' else 2500) NATIVE_DENOM = 1e9 if CHAIN == 'sol' else 1e18 def native_usd(h): return int(h.get('native_balance') or 0)/NATIVE_DENOM*NATIVE_PRICE zero_wallets = [h for h in normal if native_usd(h)==0] low_wallets = [h for h in normal if 0 < native_usd(h) <= 200] mid_wallets = [h for h in normal if 200 < native_usd(h) <= 1200] high_wallets = [h for h in normal if native_usd(h) > 1200] zero_pct_val = sum(h['amount_percentage'] for h in zero_wallets) low_pct_val = sum(h['amount_percentage'] for h in low_wallets) mid_pct_val = sum(h['amount_percentage'] for h in mid_wallets) high_pct_val = sum(h['amount_percentage'] for h in high_wallets) high_total = sum(native_usd(h) for h in high_wallets) total_buying_power = sum(native_usd(h) for h in normal)

── Wallet roles / behaviors ─────────────────────────────

── 钱包角色 / 行为 ─────────────────────────────

ROLE_MAP = { 'rat_trader': _('老鼠仓', 'Rat Trader'), 'sniper': _('狙击', 'Sniper'), 'bundler': _('捆绑', 'Bundler'), 'whale': _('鲸鱼', 'Whale'), 'smart_degen': _('聪明钱', 'Smart'), 'pump_smart': _('聪明钱', 'Smart'), 'renowned': 'KOL', 'kol': 'KOL', 'fresh_wallet': _('新钱包', 'Fresh'), 'wash_trader': _('刷量', 'Wash'), 'creator': 'Dev', 'dev_team': 'Dev', } def wallet_roles(h): roles = [] for t in (h.get('maker_token_tags') or [])+(h.get('tags') or []): if t in ROLE_MAP: roles.append(ROLE_MAP[t]) return list(dict.fromkeys(roles))
def holding_status(h): sp = h.get('sell_amount_percentage', 0) or 0 bal = h.get('balance', 0) or 0 if bal <= 0: return _("已清仓", "Cleared") if sp >= 0.8: return _("🔴 大量出货", "🔴 Heavy Selling") if sp >= 0.3: return _("🟡 出货中", "🟡 Selling") if sp > 0: return _("少量出货", "Light Selling") return _("持仓未动", "Holding")
def wallet_behavior(h): buy_tx = h.get('buy_tx_count_cur', 0) or 0 sell_tx = h.get('sell_tx_count_cur', 0) or 0 if buy_tx==0 and sell_tx==0: return _("几乎无链上活动", "Almost no on-chain activity") if buy_tx>0 and sell_tx==0: return _("持续买入,尚未卖出", "Buying only, not sold yet") if sell_tx>0 and buy_tx==0: return _("只卖不买", "Selling only") return ""
def trend_str(wlist): buying = [h for h in wlist if (h.get('buy_tx_count_cur') or 0)>0 and (h.get('sell_tx_count_cur') or 0)==0] selling = [h for h in wlist if (h.get('sell_tx_count_cur') or 0)>0 and (h.get('buy_tx_count_cur') or 0)==0] both = [h for h in wlist if (h.get('buy_tx_count_cur') or 0)>0 and (h.get('sell_tx_count_cur') or 0)>0] holding = [h for h in wlist if (h.get('buy_tx_count_cur') or 0)==0 and (h.get('sell_tx_count_cur') or 0)==0] parts = [] if buying: parts.append(f"📈 {('买入中', 'Buying')} {len(buying)}") if selling: parts.append(f"📉 {('卖出中', 'Selling')} {len(selling)}") if both: parts.append(f"🔄 {('买卖都有', 'Both')} {len(both)}") if holding: parts.append(f"🤝 {('未动', 'Holding')} {len(holding)}") return " ".join(parts) if parts else "—"
def is_active(h): return (h.get('buy_tx_count_cur') or 0)+(h.get('sell_tx_count_cur') or 0)>0 def is_selling(h): return (h.get('sell_tx_count_cur') or 0)>0 and (h.get('balance') or 0)>=1 def is_buying_only(h): return (h.get('buy_tx_count_cur') or 0)>0 and (h.get('sell_tx_count_cur') or 0)==0
ROLE_MAP = { 'rat_trader': _('老鼠仓', 'Rat Trader'), 'sniper': _('狙击', 'Sniper'), 'bundler': _('捆绑', 'Bundler'), 'whale': _('鲸鱼', 'Whale'), 'smart_degen': _('聪明钱', 'Smart'), 'pump_smart': _('聪明钱', 'Smart'), 'renowned': 'KOL', 'kol': 'KOL', 'fresh_wallet': _('新钱包', 'Fresh'), 'wash_trader': _('刷量', 'Wash'), 'creator': 'Dev', 'dev_team': 'Dev', } def wallet_roles(h): roles = [] for t in (h.get('maker_token_tags') or [])+(h.get('tags') or []): if t in ROLE_MAP: roles.append(ROLE_MAP[t]) return list(dict.fromkeys(roles))
def holding_status(h): sp = h.get('sell_amount_percentage', 0) or 0 bal = h.get('balance', 0) or 0 if bal <= 0: return _("已清仓", "Cleared") if sp >= 0.8: return _("🔴 大量出货", "🔴 Heavy Selling") if sp >= 0.3: return _("🟡 出货中", "🟡 Selling") if sp > 0: return _("少量出货", "Light Selling") return _("持仓未动", "Holding")
def wallet_behavior(h): buy_tx = h.get('buy_tx_count_cur', 0) or 0 sell_tx = h.get('sell_tx_count_cur', 0) or 0 if buy_tx==0 and sell_tx==0: return _("几乎无链上活动", "Almost no on-chain activity") if buy_tx>0 and sell_tx==0: return _("持续买入,尚未卖出", "Buying only, not sold yet") if sell_tx>0 and buy_tx==0: return _("只卖不买", "Selling only") return ""
def trend_str(wlist): buying = [h for h in wlist if (h.get('buy_tx_count_cur') or 0)>0 and (h.get('sell_tx_count_cur') or 0)==0] selling = [h for h in wlist if (h.get('sell_tx_count_cur') or 0)>0 and (h.get('buy_tx_count_cur') or 0)==0] both = [h for h in wlist if (h.get('buy_tx_count_cur') or 0)>0 and (h.get('sell_tx_count_cur') or 0)>0] holding = [h for h in wlist if (h.get('buy_tx_count_cur') or 0)==0 and (h.get('sell_tx_count_cur') or 0)==0] parts = [] if buying: parts.append(f"📈 {('买入中', 'Buying')} {len(buying)}") if selling: parts.append(f"📉 {('卖出中', 'Selling')} {len(selling)}") if both: parts.append(f"🔄 {('买卖都有', 'Both')} {len(both)}") if holding: parts.append(f"🤝 {('未动', 'Holding')} {len(holding)}") return " ".join(parts) if parts else "—"
def is_active(h): return (h.get('buy_tx_count_cur') or 0)+(h.get('sell_tx_count_cur') or 0)>0 def is_selling(h): return (h.get('sell_tx_count_cur') or 0)>0 and (h.get('balance') or 0)>=1 def is_buying_only(h): return (h.get('buy_tx_count_cur') or 0)>0 and (h.get('sell_tx_count_cur') or 0)==0

── Rating ───────────────────────────────────────────────

── 评级 ───────────────────────────────────────────────

biggest = max(normal, key=lambda h: h['amount_percentage']) if normal else None dangers = [] if rats and rats_pct > 0.1: dangers.append(( f"老鼠仓持仓 {pct(rats_pct):.1f}%,出货即砸盘", f"Rat traders hold {pct(rats_pct):.1f}% — instant dump risk")) if biggest and biggest['amount_percentage'] > 0.15: dangers.append(( f"最大单钱包持仓 {pct(biggest['amount_percentage']):.1f}%,筹码极度集中", f"Largest wallet holds {pct(biggest['amount_percentage']):.1f}% — extreme concentration")) if creator: to_out = creator.get('token_transfer_out') or {} if (to_out.get('address') or '') in top100_map: dangers.append(_("Dev 筹码转给内部马甲,换手控盘", "Dev transferred chips to internal wallet — covert control"))
warns = [] if dev_holding: hold_pct_val = sum(d.get('amount_percentage',0) for d in dev_holding) if hold_pct_val > 0.01: warns.append(( f"Dev 仍持仓 {pct(hold_pct_val):.2f}%", f"Dev still holds {pct(hold_pct_val):.2f}%")) if airdrop_pct > 0.15: warns.append(( f"空降筹码 {pct(airdrop_pct):.1f}%,来源不透明", f"Airdrop supply {pct(airdrop_pct):.1f}% — opaque origin")) if risk_pct > 0.3: warns.append(( f"风险钱包持仓 {pct(risk_pct):.1f}%,筹码质量差", f"Risk wallets hold {pct(risk_pct):.1f}% — low chip quality")) if related_pct > 0.1: warns.append(( f"关联钱包 {len(related)} 个持仓 {pct(related_pct):.1f}%", f"Linked wallets ({len(related)}) hold {pct(related_pct):.1f}%"))
if dangers: rating_em, rating_text = "🔴", _("不建议买", "Not Recommended") elif len(warns) >= 2: rating_em, rating_text = "⚠️", _("谨慎参与", "Caution") elif len(warns) == 1: rating_em, rating_text = "🟡", _("可轻仓", "Light Position") else: rating_em, rating_text = "✅", _("正常参与", "Normal")
goods = [] if burn_pct > 0.05: goods.append(( f"销毁 {pct(burn_pct):.1f}% 永久锁仓,流通减少", f"Burned {pct(burn_pct):.1f}% permanently — reduced supply")) if whales: buying_w = [h for h in whales if is_buying_only(h)] if buying_w: goods.append(( f"鲸鱼 {len(buying_w)} 个持续买入,尚未出货", f"{len(buying_w)} whale(s) still accumulating, not sold")) if kol: goods.append(( f"KOL {len(kol)} 个在场({pct(kol_pct):.2f}%)", f"{len(kol)} KOL(s) holding ({pct(kol_pct):.2f}%)")) if diamond_pct > 0.4: goods.append(( f"钻石手持仓 {pct(diamond_pct):.1f}%,筹码稳定", f"Diamond hands hold {pct(diamond_pct):.1f}% — stable chips"))
exit_signals = [] if rats: exit_signals.append(("老鼠仓钱包出现卖出操作", "Rat trader wallets start selling")) if dev_holding: exit_signals.append(("Dev 钱包开始出货", "Dev wallets start dumping")) if airdrop_pct>0.15: exit_signals.append(("空降大户出现集中卖出", "Airdrop whales start concentrated selling")) if not exit_signals: exit_signals = [("Top5 大户出现集中出货", "Top 5 holders start concentrated selling"), _("价格跌破建仓均价支撑", "Price breaks below average entry cost")] exit_signals = exit_signals[:3]
biggest = max(normal, key=lambda h: h['amount_percentage']) if normal else None dangers = [] if rats and rats_pct > 0.1: dangers.append(( f"老鼠仓持仓 {pct(rats_pct):.1f}%,出货即砸盘", f"Rat traders hold {pct(rats_pct):.1f}% — instant dump risk")) if biggest and biggest['amount_percentage'] > 0.15: dangers.append(( f"最大单钱包持仓 {pct(biggest['amount_percentage']):.1f}%,筹码极度集中", f"Largest wallet holds {pct(biggest['amount_percentage']):.1f}% — extreme concentration")) if creator: to_out = creator.get('token_transfer_out') or {} if (to_out.get('address') or '') in top100_map: dangers.append(_("Dev 筹码转给内部马甲,换手控盘", "Dev transferred chips to internal wallet — covert control"))
warns = [] if dev_holding: hold_pct_val = sum(d.get('amount_percentage',0) for d in dev_holding) if hold_pct_val > 0.01: warns.append(( f"Dev 仍持仓 {pct(hold_pct_val):.2f}%", f"Dev still holds {pct(hold_pct_val):.2f}%")) if airdrop_pct > 0.15: warns.append(( f"空降筹码 {pct(airdrop_pct):.1f}%,来源不透明", f"Airdrop supply {pct(airdrop_pct):.1f}% — opaque origin")) if risk_pct > 0.3: warns.append(( f"风险钱包持仓 {pct(risk_pct):.1f}%,筹码质量差", f"Risk wallets hold {pct(risk_pct):.1f}% — low chip quality")) if related_pct > 0.1: warns.append(( f"关联钱包 {len(related)} 个持仓 {pct(related_pct):.1f}%", f"Linked wallets ({len(related)}) hold {pct(related_pct):.1f}%"))
if dangers: rating_em, rating_text = "🔴", _("不建议买", "Not Recommended") elif len(warns) >= 2: rating_em, rating_text = "⚠️", _("谨慎参与", "Caution") elif len(warns) == 1: rating_em, rating_text = "🟡", _("可轻仓", "Light Position") else: rating_em, rating_text = "✅", _("正常参与", "Normal")
goods = [] if burn_pct > 0.05: goods.append(( f"销毁 {pct(burn_pct):.1f}% 永久锁仓,流通减少", f"Burned {pct(burn_pct):.1f}% permanently — reduced supply")) if whales: buying_w = [h for h in whales if is_buying_only(h)] if buying_w: goods.append(( f"鲸鱼 {len(buying_w)} 个持续买入,尚未出货", f"{len(buying_w)} whale(s) still accumulating, not sold")) if kol: goods.append(( f"KOL {len(kol)} 个在场({pct(kol_pct):.2f}%)", f"{len(kol)} KOL(s) holding ({pct(kol_pct):.2f}%)")) if diamond_pct > 0.4: goods.append(( f"钻石手持仓 {pct(diamond_pct):.1f}%,筹码稳定", f"Diamond hands hold {pct(diamond_pct):.1f}% — stable chips"))
exit_signals = [] if rats: exit_signals.append(("老鼠仓钱包出现卖出操作", "Rat trader wallets start selling")) if dev_holding: exit_signals.append(("Dev 钱包开始出货", "Dev wallets start dumping")) if airdrop_pct>0.15: exit_signals.append(("空降大户出现集中卖出", "Airdrop whales start concentrated selling")) if not exit_signals: exit_signals = [("Top5 大户出现集中出货", "Top 5 holders start concentrated selling"), _("价格跌破建仓均价支撑", "Price breaks below average entry cost")] exit_signals = exit_signals[:3]

── Top5 pressure analysis ───────────────────────────────

── Top5 抛压分析 ───────────────────────────────

top5_holders = sorted(normal, key=lambda h: -h['amount_percentage'])[:5]
def top5_pressure(h): avg_cost = h.get('avg_cost') or 0 up_pnl = h.get('unrealized_pnl') or 0 up_usd = h.get('unrealized_profit') or 0 buy0 = h.get('buy_tx_count_cur',0)==0 roles = wallet_roles(h) if buy0 and not roles: roles.append(_('空降', 'Airdrop')) role_str = "["+"·".join(roles)+"] " if roles else "" display_id = (h.get('twitter_name') or '') or addr_short(h['address']) if buy0 or avg_cost==0: cost_str = _("零成本(转账获得)", "Zero cost (received via transfer)") pnl_str = "—" lv = "⚠️ " + ("高", "High") note = ("零成本,随时可出货", "Zero cost — can dump anytime") elif up_pnl>1.0: mult = up_pnl+1 cost_str = f"{('均价', 'avg')} ${avg_cost:.4f}" pnl_str = f"+{up_pnl100:.0f}% ({mult:.1f}x) {usd(up_usd)}" lv = "⚠️ " + _("高", "High") note = _(f"建仓MC {usd(total_supplyavg_cost)} → 现 {usd(cur_mc)},浮盈 {mult:.1f}x 压力强", f"Entry MC {usd(total_supply*avg_cost)} → now {usd(cur_mc)}, {mult:.1f}x gain — strong pressure") elif up_pnl>0.1: cost_str = f"{('均价', 'avg')} ${avg_cost:.4f}" pnl_str = f"+{up_pnl100:.0f}% {usd(up_usd)}" lv = "🟡 " + _("中", "Med") note = ("小幅浮盈,出货意愿一般", "Moderate gain — mild sell pressure") elif up_pnl>=-0.1: cost_str = f"{('均价', 'avg')} ${avg_cost:.4f}" pnl_str = f"{up_pnl100:+.0f}% {usd(up_usd)}" if abs(up_usd)>=1 else _("接近成本", "Near cost") lv = "🟢 " + _("低", "Low") note = ("接近成本,短期抛压有限", "Near break-even — limited short-term pressure") else: cost_str = f"{('均价', 'avg')} ${avg_cost:.4f}" pnl_str = f"{up_pnl*100:.0f}% {usd(up_usd)}" lv = "🟢 " + _("低", "Low") note = _("套牢中,短期不易割肉", "Underwater — unlikely to sell soon") beh = wallet_behavior(h) beh_str = (" " + _("行为", "behavior") + ": " + beh) if beh else "" return role_str, display_id, cost_str, pnl_str, lv, note, beh_str, holding_status(h)
top5_holders = sorted(normal, key=lambda h: -h['amount_percentage'])[:5]
def top5_pressure(h): avg_cost = h.get('avg_cost') or 0 up_pnl = h.get('unrealized_pnl') or 0 up_usd = h.get('unrealized_profit') or 0 buy0 = h.get('buy_tx_count_cur',0)==0 roles = wallet_roles(h) if buy0 and not roles: roles.append(_('空降', 'Airdrop')) role_str = "["+"·".join(roles)+"] " if roles else "" display_id = (h.get('twitter_name') or '') or addr_short(h['address']) if buy0 or avg_cost==0: cost_str = _("零成本(转账获得)", "Zero cost (received via transfer)") pnl_str = "—" lv = "⚠️ " + ("高", "High") note = ("零成本,随时可出货", "Zero cost — can dump anytime") elif up_pnl>1.0: mult = up_pnl+1 cost_str = f"{('均价', 'avg')} ${avg_cost:.4f}" pnl_str = f"+{up_pnl100:.0f}% ({mult:.1f}x) {usd(up_usd)}" lv = "⚠️ " + _("高", "High") note = _(f"建仓MC {usd(total_supplyavg_cost)} → 现 {usd(cur_mc)},浮盈 {mult:.1f}x 压力强", f"Entry MC {usd(total_supply*avg_cost)} → now {usd(cur_mc)}, {mult:.1f}x gain — strong pressure") elif up_pnl>0.1: cost_str = f"{('均价', 'avg')} ${avg_cost:.4f}" pnl_str = f"+{up_pnl100:.0f}% {usd(up_usd)}" lv = "🟡 " + _("中", "Med") note = ("小幅浮盈,出货意愿一般", "Moderate gain — mild sell pressure") elif up_pnl>=-0.1: cost_str = f"{('均价', 'avg')} ${avg_cost:.4f}" pnl_str = f"{up_pnl100:+.0f}% {usd(up_usd)}" if abs(up_usd)>=1 else _("接近成本", "Near cost") lv = "🟢 " + _("低", "Low") note = ("接近成本,短期抛压有限", "Near break-even — limited short-term pressure") else: cost_str = f"{('均价', 'avg')} ${avg_cost:.4f}" pnl_str = f"{up_pnl*100:.0f}% {usd(up_usd)}" lv = "🟢 " + _("低", "Low") note = _("套牢中,短期不易割肉", "Underwater — unlikely to sell soon") beh = wallet_behavior(h) beh_str = (" " + _("行为", "behavior") + ": " + beh) if beh else "" return role_str, display_id, cost_str, pnl_str, lv, note, beh_str, holding_status(h)

══════════════════════════════════════════════════════════

══════════════════════════════════════════════════════════

OUTPUT

输出

══════════════════════════════════════════════════════════

══════════════════════════════════════════════════════════

title = _("Holder 筹码分析", "Holder Chip Analysis") print(f"┌{'─'*56}┐") print(f"│{(' '+title):^56}│") print(f"│{(' '+TOKEN_ADDR[:10]+'...'+TOKEN_ADDR[-4:]+' · Top100 · '+CHAIN.upper()):^56}│") print(f"│{(' MC '+usd(cur_mc)):^56}│") print(f"└{'─'*56}┘") print()
title = _("Holder 筹码分析", "Holder Chip Analysis") print(f"┌{'─'*56}┐") print(f"│{(' '+title):^56}│") print(f"│{(' '+TOKEN_ADDR[:10]+'...'+TOKEN_ADDR[-4:]+' · Top100 · '+CHAIN.upper()):^56}│") print(f"│{(' MC '+usd(cur_mc)):^56}│") print(f"└{'─'*56}┘") print()

── Dump Risk ──

── 砸盘风险 ──

sec1 = ("🚨 砸盘风险", "🚨 Dump Risk") print(f"━━ {sec1} {'━'*(54-len(sec1))}") print() c10f = "🔴" if top10>0.5 else ("🟡" if top10>0.3 else "🟢") c20f = "🔴" if top20>0.6 else ("🟡" if top20>0.4 else "🟢") print(f" {('集中度', 'Concentration')} Top10 {pct(top10):.1f}% {c10f} Top20 {pct(top20):.1f}% {c20f}") print() if burn: print(f" 🔥 {('销毁地址', 'Burn addr')} {pct(burn_pct):.2f}% ✅ {('永久锁仓,无法流通', 'Permanently locked, non-circulating')}") print() airf = "🔴" if airdrop_pct>0.2 else ("🟡" if airdrop_pct>0.1 else "🟢") print(f" {('空降筹码(从未买入、靠转账获得)', 'Airdrop (never bought, received via transfer)')} {len(airdrop)} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(airdrop_pct):.2f}% {airf}") print() riskf = "🔴" if risk_pct>0.3 else ("🟡" if risk_pct>0.1 else "🟢") print(f" {('风险钱包', 'Risk wallets')} {('合计', 'total')} {len(risk_all)} {('个', '')} {('持仓', 'hold')} {pct(risk_pct):.2f}% {riskf}") risk_labels = [ (("老鼠仓", "Rat Trader"), rats, "🚨"), (("捆绑交易", "Bundler"), bundlers, "⚠️"), (("狙击者", "Sniper"), snipers, "⚠️"), (("新钱包", "Fresh"), fresh, ""), (("刷量", "Wash"), wash, ""), ] for label, group, flag in risk_labels: if group: gp = pct(sum(h['amount_percentage'] for h in group)) print(f" · {label:10s} {len(group):2d} {('个', '')} {('持仓', 'hold')} {gp:.2f}% {flag}") if not any([rats,bundlers,snipers,fresh,wash]): print(f" · {_('未发现风险标签钱包', 'No risk-tagged wallets found')} 🟢") print() bundler_pct_val = sum(h['amount_percentage'] for h in bundlers) sniper_pct_val = sum(h['amount_percentage'] for h in snipers) if dangers: sdp_summary = f"🔴 {dangers[0]}" elif rats_pct > 0.05: sdp_summary = ( f"🔴 老鼠仓持仓 {pct(rats_pct):.1f}%,零成本拿的,随时可以无损砸盘", f"🔴 Rat traders hold {pct(rats_pct):.1f}% at zero cost — can dump with no loss anytime") elif top10 > 0.4: sdp_summary = ( f"🟡 Top10 持仓 {pct(top10):.1f}%,筹码过于集中,大户一旦出货冲击很大", f"🟡 Top10 hold {pct(top10):.1f}% — highly concentrated, big impact if they sell") elif bundler_pct_val > 0.2: sdp_summary = ( f"🟡 捆绑钱包持仓 {pct(bundler_pct_val):.1f}%,这批是开盘机器人扫货,出货时可能集中砸盘", f"🟡 Bundlers hold {pct(bundler_pct_val):.1f}% — bot-swept at open, may dump together") elif airdrop_pct > 0.15: sdp_summary = ( f"🟡 空降筹码 {pct(airdrop_pct):.1f}%,这些人零成本拿到币,随时可能出货", f"🟡 Airdrop supply {pct(airdrop_pct):.1f}% at zero cost — may sell anytime") elif sniper_pct_val > 0.1: sdp_summary = ( f"🟡 狙击者持仓 {pct(sniper_pct_val):.1f}%,开盘低价进的,浮盈高、随时可套现", f"🟡 Snipers hold {pct(sniper_pct_val):.1f}% at launch price — high unrealized gain, may cash out") elif risk_pct > 0.1: sdp_summary = ( f"🟡 风险钱包合计持仓 {pct(risk_pct):.1f}%,需要留意动向", f"🟡 Risk wallets total {pct(risk_pct):.1f}% — watch their moves") elif burn_pct > 0.1: sdp_summary = ( f"🟢 销毁了 {pct(burn_pct):.1f}%,流通筹码少,LP 也锁住了,相对干净", f"🟢 {pct(burn_pct):.1f}% burned — reduced supply, LP locked, relatively clean") else: sdp_summary = ("🟢 集中度正常,没发现明显的砸盘风险", "🟢 Normal concentration, no obvious dump risk detected") print(f" → {('小结', 'Summary')}{(':', ': ')}{sdp_summary}") print() print(f" {('Top5 持仓钱包抛压分析', 'Top 5 Holder Sell Pressure')}") print(f" {('浮盈越高 / 建仓MC越低 → 获利了结压力越强', 'Higher unrealized gain / lower entry MC → stronger sell pressure')}") print() for i, h in enumerate(top5_holders, 1): role_str, display_id, cost_str, pnl_str, lv, note, beh_str, st = top5_pressure(h) hp = pct(h['amount_percentage']) print(f" {i}. {role_str}{display_id}") print(f" {('持仓', 'hold')} {hp:.2f}% {cost_str} {('盈亏', 'pnl')} {pnl_str}") print(f" {('抛压', 'pressure')} {lv} — {note}") print(f" {('状态', 'status')} {st}{beh_str}") print()
sec1 = ("🚨 砸盘风险", "🚨 Dump Risk") print(f"━━ {sec1} {'━'*(54-len(sec1))}") print() c10f = "🔴" if top10>0.5 else ("🟡" if top10>0.3 else "🟢") c20f = "🔴" if top20>0.6 else ("🟡" if top20>0.4 else "🟢") print(f" {('集中度', 'Concentration')} Top10 {pct(top10):.1f}% {c10f} Top20 {pct(top20):.1f}% {c20f}") print() if burn: print(f" 🔥 {('销毁地址', 'Burn addr')} {pct(burn_pct):.2f}% ✅ {('永久锁仓,无法流通', 'Permanently locked, non-circulating')}") print() airf = "🔴" if airdrop_pct>0.2 else ("🟡" if airdrop_pct>0.1 else "🟢") print(f" {('空降筹码(从未买入、靠转账获得)', 'Airdrop (never bought, received via transfer)')} {len(airdrop)} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(airdrop_pct):.2f}% {airf}") print() riskf = "🔴" if risk_pct>0.3 else ("🟡" if risk_pct>0.1 else "🟢") print(f" {('风险钱包', 'Risk wallets')} {('合计', 'total')} {len(risk_all)} {('个', '')} {('持仓', 'hold')} {pct(risk_pct):.2f}% {riskf}") risk_labels = [ (("老鼠仓", "Rat Trader"), rats, "🚨"), (("捆绑交易", "Bundler"), bundlers, "⚠️"), (("狙击者", "Sniper"), snipers, "⚠️"), (("新钱包", "Fresh"), fresh, ""), (("刷量", "Wash"), wash, ""), ] for label, group, flag in risk_labels: if group: gp = pct(sum(h['amount_percentage'] for h in group)) print(f" · {label:10s} {len(group):2d} {('个', '')} {('持仓', 'hold')} {gp:.2f}% {flag}") if not any([rats,bundlers,snipers,fresh,wash]): print(f" · {_('未发现风险标签钱包', 'No risk-tagged wallets found')} 🟢") print() bundler_pct_val = sum(h['amount_percentage'] for h in bundlers) sniper_pct_val = sum(h['amount_percentage'] for h in snipers) if dangers: sdp_summary = f"🔴 {dangers[0]}" elif rats_pct > 0.05: sdp_summary = ( f"🔴 老鼠仓持仓 {pct(rats_pct):.1f}%,零成本拿的,随时可以无损砸盘", f"🔴 Rat traders hold {pct(rats_pct):.1f}% at zero cost — can dump with no loss anytime") elif top10 > 0.4: sdp_summary = ( f"🟡 Top10 持仓 {pct(top10):.1f}%,筹码过于集中,大户一旦出货冲击很大", f"🟡 Top10 hold {pct(top10):.1f}% — highly concentrated, big impact if they sell") elif bundler_pct_val > 0.2: sdp_summary = ( f"🟡 捆绑钱包持仓 {pct(bundler_pct_val):.1f}%,这批是开盘机器人扫货,出货时可能集中砸盘", f"🟡 Bundlers hold {pct(bundler_pct_val):.1f}% — bot-swept at open, may dump together") elif airdrop_pct > 0.15: sdp_summary = ( f"🟡 空降筹码 {pct(airdrop_pct):.1f}%,这些人零成本拿到币,随时可能出货", f"🟡 Airdrop supply {pct(airdrop_pct):.1f}% at zero cost — may sell anytime") elif sniper_pct_val > 0.1: sdp_summary = ( f"🟡 狙击者持仓 {pct(sniper_pct_val):.1f}%,开盘低价进的,浮盈高、随时可套现", f"🟡 Snipers hold {pct(sniper_pct_val):.1f}% at launch price — high unrealized gain, may cash out") elif risk_pct > 0.1: sdp_summary = ( f"🟡 风险钱包合计持仓 {pct(risk_pct):.1f}%,需要留意动向", f"🟡 Risk wallets total {pct(risk_pct):.1f}% — watch their moves") elif burn_pct > 0.1: sdp_summary = ( f"🟢 销毁了 {pct(burn_pct):.1f}%,流通筹码少,LP 也锁住了,相对干净", f"🟢 {pct(burn_pct):.1f}% burned — reduced supply, LP locked, relatively clean") else: sdp_summary = ("🟢 集中度正常,没发现明显的砸盘风险", "🟢 Normal concentration, no obvious dump risk detected") print(f" → {('小结', 'Summary')}{(':', ': ')}{sdp_summary}") print() print(f" {('Top5 持仓钱包抛压分析', 'Top 5 Holder Sell Pressure')}") print(f" {('浮盈越高 / 建仓MC越低 → 获利了结压力越强', 'Higher unrealized gain / lower entry MC → stronger sell pressure')}") print() for i, h in enumerate(top5_holders, 1): role_str, display_id, cost_str, pnl_str, lv, note, beh_str, st = top5_pressure(h) hp = pct(h['amount_percentage']) print(f" {i}. {role_str}{display_id}") print(f" {('持仓', 'hold')} {hp:.2f}% {cost_str} {('盈亏', 'pnl')} {pnl_str}") print(f" {('抛压', 'pressure')} {lv} — {note}") print(f" {('状态', 'status')} {st}{beh_str}") print()

── Dev Wallets ──

── Dev 钱包 ──

sec2 = ("👨‍💻 Dev 钱包", "👨‍💻 Dev Wallets") print(f"━━ {sec2} {'━'*(54-len(sec2))}") print() dev_status = (("✅ 全部余额归零", "✅ All cleared") if not dev_holding else (f"⚠️ 仍有 {len(dev_holding)} 个持仓中", f"⚠️ {len(dev_holding)} still holding")) if sub_devs: print(f" {('共', 'Total')} {len(devs)} {('个钱包(1 主号 + ', 'wallets (1 main + ')}{len(sub_devs)}{(' 小号)', ' sub)')} {dev_status}") else: print(f" {('共', 'Total')} {len(devs)} {('个钱包', 'wallets')} {dev_status}") print(f" {('Dev 合计已实现利润', 'Dev total realized profit')} {usd(dev_realized)}") print() if creator: c_sell_v = creator.get('sell_volume_cur') or 0 tf_out = creator.get('history_transfer_out_amount') or 0 tf_val = creator.get('history_transfer_out_income') or 0 sell_amt = creator.get('sell_amount_cur') or 0 hold_pct_c = creator.get('amount_percentage') or 0 c_status = (("余额归零", "Balance zero") if (creator.get('balance') or 0)<1 else (f"⚠️ 持仓 {pct(hold_pct_c):.2f}%", f"⚠️ Holding {pct(hold_pct_c):.2f}%")) print(f" {('主号 (Creator)', 'Main (Creator)')} {addr_short(creator['address'])}") parts = [c_status] if sell_amt>0: parts.append((f"卖出 {fmt_amt(sell_amt)} 个({usd(c_sell_v)})", f"Sold {fmt_amt(sell_amt)} ({usd(c_sell_v)})")) if tf_out>0: to_out = creator.get('token_transfer_out') or {} to_addr = to_out.get('address') or '' if to_addr and to_addr in top100_map: parts.append((f"转出 {fmt_amt(tf_out)} 个至 Top100 内部钱包(估值 {usd(tf_val)})", f"Transferred {fmt_amt(tf_out)} to Top100 internal wallet (est. {usd(tf_val)})")) else: parts.append((f"转出 {fmt_amt(tf_out)} 个至外部地址(估值 {usd(tf_val)})", f"Transferred {fmt_amt(tf_out)} to external addr (est. {usd(tf_val)})")) print(f" {' '.join(parts)}") to_out = creator.get('token_transfer_out') or {} to_addr = to_out.get('address') or '' if to_addr and to_addr in top100_map: target = top100_map[to_addr] t_mtags = [t for t in (target.get('maker_token_tags') or []) if t not in ('top_holder','transfer_in')] print(f"\n ⚠️ {('转出筹码仍在 Top100(换马甲继续持有):', 'Transferred chips still in Top100 (sock puppet):')}") print(f" {addr_short(to_addr)} {('持仓', 'hold')} {pct(target.get('amount_percentage',0)):.2f}% {('标签', 'tags')}: {' '.join(t_mtags) or ('无','none')}") elif (creator.get('balance') or 0)<1 and tf_out==0: print(f" ✅ {('已完全卖出,无异常转账记录', 'Fully sold, no abnormal transfers')}") print() if to_addr and to_addr in top100_map: dev_summary = ( "🔴 Dev 换马甲持仓,这个很危险,随时可以砸盘", "🔴 Dev using sock puppet — very dangerous, can dump anytime") elif dev_holding: dev_summary = ( "🟡 Dev 还没出完,有出货风险,关注钱包动向", "🟡 Dev hasn't fully exited — dump risk, watch wallet activity") elif dev_realized > 50000: dev_summary = ( f"🟡 Dev 已套现 {usd(dev_realized)},虽然出完了但赚了不少", f"🟡 Dev cashed out {usd(dev_realized)} — exited but made significant profit") else: dev_summary = ( "🟢 Dev 已清仓,没有持仓压力", "🟢 Dev fully exited — no holding pressure") print(f" → {('小结', 'Summary')}{(':', ': ')}{dev_summary}") print() if created_data: all_tokens = created_data.get('tokens') or [] total_cnt = (created_data.get('inner_count') or 0)+(created_data.get('open_count') or 0) mig_cnt = created_data.get('open_count') or 0 nonmig_cnt = created_data.get('inner_count') or 0 print(f" {('历史发币', 'Token history')} {('共', 'total')} {total_cnt} {('已迁移', 'migrated')} {mig_cnt} {('未迁移', 'unmigrated')} {nonmig_cnt}") top3_mc = sorted(all_tokens, key=lambda t: float(t.get('market_cap') or 0), reverse=True)[:3] if top3_mc: print(f" {_('当前市值 Top3', 'Current MC Top3')}:") for i, t in enumerate(top3_mc, 1): mig_label = _('已迁移', 'migrated') if t.get('is_open') else _('未迁移', 'unmigrated') print(f" {i}. {t.get('symbol','?')} {usd(float(t.get('market_cap') or 0))} [{mig_label}]") ath_info = created_data.get('creator_ath_info') or {} if ath_info and ath_info.get('ath_mc'): is_curr = ath_info.get('ath_token','').lower()==TOKEN_ADDR.lower() curr_label = ('(本币)', ' (this token)') if is_curr else '' print(f" {('历史最高市值', 'All-time high MC')}: {ath_info.get('token_name','')}({ath_info.get('token_symbol','?')}){curr_label} ATH {usd(float(ath_info.get('ath_mc') or 0))}") print()
sec2 = ("👨‍💻 Dev 钱包", "👨‍💻 Dev Wallets") print(f"━━ {sec2} {'━'*(54-len(sec2))}") print() dev_status = (("✅ 全部余额归零", "✅ All cleared") if not dev_holding else (f"⚠️ 仍有 {len(dev_holding)} 个持仓中", f"⚠️ {len(dev_holding)} still holding")) if sub_devs: print(f" {('共', 'Total')} {len(devs)} {('个钱包(1 主号 + ', 'wallets (1 main + ')}{len(sub_devs)}{(' 小号)', ' sub)')} {dev_status}") else: print(f" {('共', 'Total')} {len(devs)} {('个钱包', 'wallets')} {dev_status}") print(f" {('Dev 合计已实现利润', 'Dev total realized profit')} {usd(dev_realized)}") print() if creator: c_sell_v = creator.get('sell_volume_cur') or 0 tf_out = creator.get('history_transfer_out_amount') or 0 tf_val = creator.get('history_transfer_out_income') or 0 sell_amt = creator.get('sell_amount_cur') or 0 hold_pct_c = creator.get('amount_percentage') or 0 c_status = (("余额归零", "Balance zero") if (creator.get('balance') or 0)<1 else (f"⚠️ 持仓 {pct(hold_pct_c):.2f}%", f"⚠️ Holding {pct(hold_pct_c):.2f}%")) print(f" {('主号 (Creator)', 'Main (Creator)')} {addr_short(creator['address'])}") parts = [c_status] if sell_amt>0: parts.append((f"卖出 {fmt_amt(sell_amt)} 个({usd(c_sell_v)})", f"Sold {fmt_amt(sell_amt)} ({usd(c_sell_v)})")) if tf_out>0: to_out = creator.get('token_transfer_out') or {} to_addr = to_out.get('address') or '' if to_addr and to_addr in top100_map: parts.append((f"转出 {fmt_amt(tf_out)} 个至 Top100 内部钱包(估值 {usd(tf_val)})", f"Transferred {fmt_amt(tf_out)} to Top100 internal wallet (est. {usd(tf_val)})")) else: parts.append((f"转出 {fmt_amt(tf_out)} 个至外部地址(估值 {usd(tf_val)})", f"Transferred {fmt_amt(tf_out)} to external addr (est. {usd(tf_val)})")) print(f" {' '.join(parts)}") to_out = creator.get('token_transfer_out') or {} to_addr = to_out.get('address') or '' if to_addr and to_addr in top100_map: target = top100_map[to_addr] t_mtags = [t for t in (target.get('maker_token_tags') or []) if t not in ('top_holder','transfer_in')] print(f"\n ⚠️ {('转出筹码仍在 Top100(换马甲继续持有):', 'Transferred chips still in Top100 (sock puppet):')}") print(f" {addr_short(to_addr)} {('持仓', 'hold')} {pct(target.get('amount_percentage',0)):.2f}% {('标签', 'tags')}: {' '.join(t_mtags) or ('无','none')}") elif (creator.get('balance') or 0)<1 and tf_out==0: print(f" ✅ {('已完全卖出,无异常转账记录', 'Fully sold, no abnormal transfers')}") print() if to_addr and to_addr in top100_map: dev_summary = ( "🔴 Dev 换马甲持仓,这个很危险,随时可以砸盘", "🔴 Dev using sock puppet — very dangerous, can dump anytime") elif dev_holding: dev_summary = ( "🟡 Dev 还没出完,有出货风险,关注钱包动向", "🟡 Dev hasn't fully exited — dump risk, watch wallet activity") elif dev_realized > 50000: dev_summary = ( f"🟡 Dev 已套现 {usd(dev_realized)},虽然出完了但赚了不少", f"🟡 Dev cashed out {usd(dev_realized)} — exited but made significant profit") else: dev_summary = ( "🟢 Dev 已清仓,没有持仓压力", "🟢 Dev fully exited — no holding pressure") print(f" → {('小结', 'Summary')}{(':', ': ')}{dev_summary}") print() if created_data: all_tokens = created_data.get('tokens') or [] total_cnt = (created_data.get('inner_count') or 0)+(created_data.get('open_count') or 0) mig_cnt = created_data.get('open_count') or 0 nonmig_cnt = created_data.get('inner_count') or 0 print(f" {('历史发币', 'Token history')} {('共', 'total')} {total_cnt} {('已迁移', 'migrated')} {mig_cnt} {('未迁移', 'unmigrated')} {nonmig_cnt}") top3_mc = sorted(all_tokens, key=lambda t: float(t.get('market_cap') or 0), reverse=True)[:3] if top3_mc: print(f" {_('当前市值 Top3', 'Current MC Top3')}:") for i, t in enumerate(top3_mc, 1): mig_label = _('已迁移', 'migrated') if t.get('is_open') else _('未迁移', 'unmigrated') print(f" {i}. {t.get('symbol','?')} {usd(float(t.get('market_cap') or 0))} [{mig_label}]") ath_info = created_data.get('creator_ath_info') or {} if ath_info and ath_info.get('ath_mc'): is_curr = ath_info.get('ath_token','').lower()==TOKEN_ADDR.lower() curr_label = ('(本币)', ' (this token)') if is_curr else '' print(f" {('历史最高市值', 'All-time high MC')}: {ath_info.get('token_name','')}({ath_info.get('token_symbol','?')}){curr_label} ATH {usd(float(ath_info.get('ath_mc') or 0))}") print()

── Related Funds ──

── 关联资金 ──

sec3 = ("🔗 关联资金", "🔗 Related Funds") print(f"━━ {sec3} {'━'*(54-len(sec3))}") print() print(f" {('多个钱包来自同一资金来源地址,或在极短时间内同步注资', 'Multiple wallets from same funding source or funded in tight time windows')}") print() if related: relf = "🔴" if related_pct>0.15 else ("🟡" if related_pct>0.05 else "🟢") print(f" {('涉及', 'Involves')} {len(related)} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(related_pct):.2f}% {usd(related_usd)} {relf}") print() print(f" ├─ {('同一资金来源地址', 'Same funding source')} {len(same_src_groups)} {('组', 'groups')} / {same_src_wallets} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(same_src_pct):.2f}%") if same_src_groups: fa, ws = same_src_groups[0] native_in = sum(float((w.get('native_transfer') or {}).get('amount',0) or 0) for w in ws) native_sym = 'SOL' if CHAIN=='sol' else ('BNB' if CHAIN=='bsc' else 'ETH') print(f" │ {('最大组', 'Largest group')}: {len(ws)} {('个钱包', 'wallets')} {('同一地址先后转入启动资金', 'funded sequentially from same addr')} {native_in:.4f} {native_sym}") print(f" │") if win_groups: win_total = sum(len(v) for __,v in win_groups) if win_total>=3: k,v = win_groups[0] print(f" └─ {('同期注资(30min内集中入场)', 'Coordinated funding (within 30min)')} {win_total} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(win_pct):.2f}% ⚠️") print(f" {('最大批次', 'Largest batch')}: {len(v)} {('个钱包', 'wallets')} {('合计持仓', 'total hold')} {pct(sum(h['amount_percentage'] for h in v)):.3f}%") else: print(f" └─ {('同期注资(30min内集中入场)', 'Coordinated funding (within 30min)')} {win_total} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(win_pct):.2f}%") else: print(f" └─ {('未发现同期集中注资', 'No coordinated funding detected')}") else: print(f" {_('未发现明显关联资金', 'No significant linked funds detected')} 🟢") print()
sec3 = ("🔗 关联资金", "🔗 Related Funds") print(f"━━ {sec3} {'━'*(54-len(sec3))}") print() print(f" {('多个钱包来自同一资金来源地址,或在极短时间内同步注资', 'Multiple wallets from same funding source or funded in tight time windows')}") print() if related: relf = "🔴" if related_pct>0.15 else ("🟡" if related_pct>0.05 else "🟢") print(f" {('涉及', 'Involves')} {len(related)} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(related_pct):.2f}% {usd(related_usd)} {relf}") print() print(f" ├─ {('同一资金来源地址', 'Same funding source')} {len(same_src_groups)} {('组', 'groups')} / {same_src_wallets} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(same_src_pct):.2f}%") if same_src_groups: fa, ws = same_src_groups[0] native_in = sum(float((w.get('native_transfer') or {}).get('amount',0) or 0) for w in ws) native_sym = 'SOL' if CHAIN=='sol' else ('BNB' if CHAIN=='bsc' else 'ETH') print(f" │ {('最大组', 'Largest group')}: {len(ws)} {('个钱包', 'wallets')} {('同一地址先后转入启动资金', 'funded sequentially from same addr')} {native_in:.4f} {native_sym}") print(f" │") if win_groups: win_total = sum(len(v) for __,v in win_groups) if win_total>=3: k,v = win_groups[0] print(f" └─ {('同期注资(30min内集中入场)', 'Coordinated funding (within 30min)')} {win_total} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(win_pct):.2f}% ⚠️") print(f" {('最大批次', 'Largest batch')}: {len(v)} {('个钱包', 'wallets')} {('合计持仓', 'total hold')} {pct(sum(h['amount_percentage'] for h in v)):.3f}%") else: print(f" └─ {('同期注资(30min内集中入场)', 'Coordinated funding (within 30min)')} {win_total} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(win_pct):.2f}%") else: print(f" └─ {('未发现同期集中注资', 'No coordinated funding detected')}") else: print(f" {_('未发现明显关联资金', 'No significant linked funds detected')} 🟢") print()

── Quality Signals ──

── 优质信号 ──

sec4 = ("🧠 优质信号", "🧠 Quality Signals") print(f"━━ {sec4} {'━'*(54-len(sec4))}") print() print(f" {('聪明钱', 'Smart Money')} {len(smart):2d} {('持仓', 'hold')} {pct(smart_pct):.2f}% {'✅' if smart else '—'}") if smart: print(f" {('近期动向', 'Recent')}: {trend_str(smart)}") print(f" KOL {len(kol):2d} {('持仓', 'hold')} {pct(kol_pct):.2f}% {'✅' if kol else '—'}") if kol: for h in kol: name = h.get('twitter_name') or h.get('name') or addr_short(h['address']) print(f" · {name} {('持仓', 'hold')} {pct(h['amount_percentage']):.2f}% {holding_status(h)} {('买/卖', 'buy/sell')}: {h.get('buy_tx_count_cur',0)}/{h.get('sell_tx_count_cur',0)}") print(f" {('鲸鱼', 'Whale')} {len(whales):2d} {('持仓', 'hold')} {pct(whale_pct):.2f}% {'✅' if whales else '—'}") if whales: print(f" {('近期动向', 'Recent')}: {trend_str(whales)}") print() df = "✅" if diamond_pct>0.5 else ("🟡" if diamond_pct>0.3 else "⚠️") print(f" {('钻石手(从未卖出)', 'Diamond hands (never sold)')} {len(diamond):2d} {('持仓', 'hold')} {pct(diamond_pct):.1f}% {df}") print(f" {('部分卖出(<50%)', 'Partial sell (<50%)')} {len(partial):2d} {('大量卖出(≥50%)', 'Heavy sell (≥50%)')} {len(heavy_sell):2d}") sig_count = len(smart) + len(kol) + len(whales) kol_selling = [h for h in kol if (h.get('sell_tx_count_cur') or 0) > 0] kol_holding = [h for h in kol if (h.get('sell_tx_count_cur') or 0) == 0 and (h.get('balance') or 0) >= 1] smart_selling = [h for h in smart if (h.get('sell_tx_count_cur') or 0) > 0] smart_holding = [h for h in smart if (h.get('sell_tx_count_cur') or 0) == 0 and (h.get('balance') or 0) >= 1] if sig_count == 0: sig_summary = _("🟡 没有聪明钱和KOL,这个币没什么外部背书", "🟡 No smart money or KOL — no external endorsement") elif kol_selling and len(kol_selling) >= max(1, len(kol)//2+1): sig_summary = _(f"🟡 {len(kol)}个KOL里有{len(kol_selling)}个已开始卖——跟进要小心", f"🟡 {len(kol_selling)}/{len(kol)} KOL(s) already selling — be careful following") elif smart_selling and len(smart_selling) >= max(1, len(smart)//2+1): sig_summary = _(f"🟡 聪明钱里有{len(smart_selling)}个已经在出货,信号在减弱", f"🟡 {len(smart_selling)} smart money wallet(s) selling — signal weakening") elif smart_holding: sig_summary = _(f"🟢 {len(smart_holding)}个聪明钱一直持仓没卖,这类人通常提前判断,信号较强", f"🟢 {len(smart_holding)} smart money wallet(s) holding firm — usually early movers, strong signal") elif kol_holding: sig_summary = (f"🟢 {len(kol_holding)}个KOL全程持仓未卖,参考价值保留", f"🟢 {len(kol_holding)} KOL(s) fully holding — signal still valid") else: sig_summary = ("🟢 鲸鱼在场,有大资金背书", "🟢 Whales present — backed by large capital") print(f" → {('小结', 'Summary')}{(':', ': ')}{sig_summary}") print()
sec4 = ("🧠 优质信号", "🧠 Quality Signals") print(f"━━ {sec4} {'━'*(54-len(sec4))}") print() print(f" {('聪明钱', 'Smart Money')} {len(smart):2d} {('持仓', 'hold')} {pct(smart_pct):.2f}% {'✅' if smart else '—'}") if smart: print(f" {('近期动向', 'Recent')}: {trend_str(smart)}") print(f" KOL {len(kol):2d} {('持仓', 'hold')} {pct(kol_pct):.2f}% {'✅' if kol else '—'}") if kol: for h in kol: name = h.get('twitter_name') or h.get('name') or addr_short(h['address']) print(f" · {name} {('持仓', 'hold')} {pct(h['amount_percentage']):.2f}% {holding_status(h)} {('买/卖', 'buy/sell')}: {h.get('buy_tx_count_cur',0)}/{h.get('sell_tx_count_cur',0)}") print(f" {('鲸鱼', 'Whale')} {len(whales):2d} {('持仓', 'hold')} {pct(whale_pct):.2f}% {'✅' if whales else '—'}") if whales: print(f" {('近期动向', 'Recent')}: {trend_str(whales)}") print() df = "✅" if diamond_pct>0.5 else ("🟡" if diamond_pct>0.3 else "⚠️") print(f" {('钻石手(从未卖出)', 'Diamond hands (never sold)')} {len(diamond):2d} {('持仓', 'hold')} {pct(diamond_pct):.1f}% {df}") print(f" {('部分卖出(<50%)', 'Partial sell (<50%)')} {len(partial):2d} {('大量卖出(≥50%)', 'Heavy sell (≥50%)')} {len(heavy_sell):2d}") sig_count = len(smart) + len(kol) + len(whales) kol_selling = [h for h in kol if (h.get('sell_tx_count_cur') or 0) > 0] kol_holding = [h for h in kol if (h.get('sell_tx_count_cur') or 0) == 0 and (h.get('balance') or 0) >= 1] smart_selling = [h for h in smart if (h.get('sell_tx_count_cur') or 0) > 0] smart_holding = [h for h in smart if (h.get('sell_tx_count_cur') or 0) == 0 and (h.get('balance') or 0) >= 1] if sig_count == 0: sig_summary = _("🟡 没有聪明钱和KOL,这个币没什么外部背书", "🟡 No smart money or KOL — no external endorsement") elif kol_selling and len(kol_selling) >= max(1, len(kol)//2+1): sig_summary = _(f"🟡 {len(kol)}个KOL里有{len(kol_selling)}个已开始卖——跟进要小心", f"🟡 {len(kol_selling)}/{len(kol)} KOL(s) already selling — be careful following") elif smart_selling and len(smart_selling) >= max(1, len(smart)//2+1): sig_summary = _(f"🟡 聪明钱里有{len(smart_selling)}个已经在出货,信号在减弱", f"🟡 {len(smart_selling)} smart money wallet(s) selling — signal weakening") elif smart_holding: sig_summary = _(f"🟢 {len(smart_holding)}个聪明钱一直持仓没卖,这类人通常提前判断,信号较强", f"🟢 {len(smart_holding)} smart money wallet(s) holding firm — usually early movers, strong signal") elif kol_holding: sig_summary = (f"🟢 {len(kol_holding)}个KOL全程持仓未卖,参考价值保留", f"🟢 {len(kol_holding)} KOL(s) fully holding — signal still valid") else: sig_summary = ("🟢 鲸鱼在场,有大资金背书", "🟢 Whales present — backed by large capital") print(f" → {('小结', 'Summary')}{(':', ': ')}{sig_summary}") print()

── Entry Cost Analysis ──

── 入场成本分析 ──

sec5 = ("📈 入场成本分析", "📈 Entry Cost Analysis") print(f"━━ {sec5} {'━'*(54-len(sec5))}") print() print(f" {('当前 MC', 'Current MC')} {usd(cur_mc)}") print() time_clusters = defaultdict(list) for h in normal: sh = h.get('start_holding_at') or 0 if sh<=0: continue time_clusters[(sh-token_launch)//86400].append(h) sig_clusters = sorted([(age,ws) for age,ws in time_clusters.items() if len(ws)>=2], key=lambda x: -sum(h['amount_percentage'] for h in x[1]))[:4]
for rank, (age, ws) in enumerate(sig_clusters, 1): entry_ts = token_launch + age86400 label = age_label(entry_ts) total_hp = sum(h['amount_percentage'] for h in ws) costed = [h for h in ws if (h.get('avg_cost') or 0)>0] selling_out = [h for h in ws if holding_status(h) in ( _('🔴 大量出货','🔴 Heavy Selling'), _('🟡 出货中','🟡 Selling'))] still_hold = [h for h in ws if (h.get('balance') or 0)>=1] if costed: avg_entry = sum(total_supplyh['avg_cost'] for h in costed)/len(costed) roi = (cur_mc-avg_entry)/avg_entry*100 if avg_entry>0 else 0 mc_str = (f"建仓MC {usd(avg_entry)} → 现 {usd(cur_mc)} ({roi:+.0f}%)", f"Entry MC {usd(avg_entry)} → now {usd(cur_mc)} ({roi:+.0f}%)") else: avg_entry=0; roi=0 mc_str = ("建仓MC 未知(转账获得)", "Entry MC unknown (received via transfer)") sell_ratio = len(selling_out)/len(still_hold) if still_hold else 0 if roi>500 and sell_ratio>0.15: risk_flag = "🔴" conclusion = (f"这批人建仓时才 {usd(avg_entry)},涨了 {roi:.0f}%,现在有 {len(selling_out)} 个在卖出套现——追入容易接到他们的盘", f"Entry at {usd(avg_entry)}, up {roi:.0f}%, {len(selling_out)} already selling — buying now means catching their exits") elif roi>200 and sell_ratio>0.1: risk_flag = "🟡" conclusion = (f"涨了 {roi:.0f}%,有 {len(selling_out)} 个开始出货,但多数还没动——注意大户下一步动向", f"Up {roi:.0f}%, {len(selling_out)} starting to sell but most still holding — watch whale next moves") elif roi>0: risk_flag = "🟢" conclusion = (f"涨了 {roi:.0f}%,出货的人不多,短期卖压不大", f"Up {roi:.0f}%, few selling — limited short-term pressure") else: risk_flag = "🟢" conclusion = (f"这批人目前亏着呢({roi:.0f}%),不到割肉的程度,短期不太会卖", f"Currently down {roi:.0f}% — unlikely to sell at a loss short-term") batch_label = ('批次', 'Batch') print(f" {batch_label}{rank}{('(', '(')}{label}{(')', ')')} {len(ws)} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(total_hp):.2f}% {risk_flag}") print(f" {mc_str}") print(f" ➤ {conclusion}") print() notable = sorted([h for h in ws if h.get('balance',0)>=1 and h['amount_percentage']>=0.002], key=lambda h: -h['amount_percentage']) if not notable: notable = sorted([h for h in ws if h.get('balance',0)>=1], key=lambda h: -h['amount_percentage'])[:5] dumping = [h for h in notable if is_selling(h)] holding_firm = [h for h in notable if is_buying_only(h)] silent_list = [h for h in notable if not is_active(h)] if dumping: print(f" 🚨 {('出货中的大户', 'Selling whales')}") for h in dumping[:3]: did = (h.get('twitter_name') or '') or addr_short(h['address']) roles = wallet_roles(h) role_s = "["+"·".join(roles)+"] " if roles else "" print(f" · {role_s}{did} {pct(h['amount_percentage']):.2f}% {('浮盈','pnl')}{(h.get('unrealized_pnl') or 0)*100:+.0f}% {('已卖','sold')} {h.get('sell_tx_count_cur') or 0}x {holding_status(h)}") print() if holding_firm: print(f" 📈 {('持续加仓/未出货', 'Still accumulating / not sold')}") for h in holding_firm[:3]: did = (h.get('twitter_name') or '') or addr_short(h['address']) roles = wallet_roles(h) role_s = "["+"·".join(roles)+"] " if roles else "" print(f" · {role_s}{did} {pct(h['amount_percentage']):.2f}% {('浮盈','pnl')}{(h.get('unrealized_pnl') or 0)*100:+.0f}% {('已买','bought')} {h.get('buy_tx_count_cur') or 0}x") print() if silent_list: silent_pct_val = sum(h['amount_percentage'] for h in silent_list) buy0_cnt = sum(1 for h in silent_list if h.get('buy_tx_count_cur',0)==0) note_str = (("零成本空降为主", "mostly zero-cost airdrop") if buy0_cnt>len(silent_list)//2 else ("持仓未动", "holding without activity")) print(f" 💤 {('静默持仓', 'Silent holders')} {len(silent_list)} {pct(silent_pct_val):.2f}% → {_('抛压低,', 'low pressure, ')}{note_str}") print() print()
sec5 = ("📈 入场成本分析", "📈 Entry Cost Analysis") print(f"━━ {sec5} {'━'*(54-len(sec5))}") print() print(f" {('当前 MC', 'Current MC')} {usd(cur_mc)}") print() time_clusters = defaultdict(list) for h in normal: sh = h.get('start_holding_at') or 0 if sh<=0: continue time_clusters[(sh-token_launch)//86400].append(h) sig_clusters = sorted([(age,ws) for age,ws in time_clusters.items() if len(ws)>=2], key=lambda x: -sum(h['amount_percentage'] for h in x[1]))[:4]
for rank, (age, ws) in enumerate(sig_clusters, 1): entry_ts = token_launch + age86400 label = age_label(entry_ts) total_hp = sum(h['amount_percentage'] for h in ws) costed = [h for h in ws if (h.get('avg_cost') or 0)>0] selling_out = [h for h in ws if holding_status(h) in ( _('🔴 大量出货','🔴 Heavy Selling'), _('🟡 出货中','🟡 Selling'))] still_hold = [h for h in ws if (h.get('balance') or 0)>=1] if costed: avg_entry = sum(total_supplyh['avg_cost'] for h in costed)/len(costed) roi = (cur_mc-avg_entry)/avg_entry*100 if avg_entry>0 else 0 mc_str = (f"建仓MC {usd(avg_entry)} → 现 {usd(cur_mc)} ({roi:+.0f}%)", f"Entry MC {usd(avg_entry)} → now {usd(cur_mc)} ({roi:+.0f}%)") else: avg_entry=0; roi=0 mc_str = ("建仓MC 未知(转账获得)", "Entry MC unknown (received via transfer)") sell_ratio = len(selling_out)/len(still_hold) if still_hold else 0 if roi>500 and sell_ratio>0.15: risk_flag = "🔴" conclusion = (f"这批人建仓时才 {usd(avg_entry)},涨了 {roi:.0f}%,现在有 {len(selling_out)} 个在卖出套现——追入容易接到他们的盘", f"Entry at {usd(avg_entry)}, up {roi:.0f}%, {len(selling_out)} already selling — buying now means catching their exits") elif roi>200 and sell_ratio>0.1: risk_flag = "🟡" conclusion = (f"涨了 {roi:.0f}%,有 {len(selling_out)} 个开始出货,但多数还没动——注意大户下一步动向", f"Up {roi:.0f}%, {len(selling_out)} starting to sell but most still holding — watch whale next moves") elif roi>0: risk_flag = "🟢" conclusion = (f"涨了 {roi:.0f}%,出货的人不多,短期卖压不大", f"Up {roi:.0f}%, few selling — limited short-term pressure") else: risk_flag = "🟢" conclusion = (f"这批人目前亏着呢({roi:.0f}%),不到割肉的程度,短期不太会卖", f"Currently down {roi:.0f}% — unlikely to sell at a loss short-term") batch_label = ('批次', 'Batch') print(f" {batch_label}{rank}{('(', '(')}{label}{(')', ')')} {len(ws)} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(total_hp):.2f}% {risk_flag}") print(f" {mc_str}") print(f" ➤ {conclusion}") print() notable = sorted([h for h in ws if h.get('balance',0)>=1 and h['amount_percentage']>=0.002], key=lambda h: -h['amount_percentage']) if not notable: notable = sorted([h for h in ws if h.get('balance',0)>=1], key=lambda h: -h['amount_percentage'])[:5] dumping = [h for h in notable if is_selling(h)] holding_firm = [h for h in notable if is_buying_only(h)] silent_list = [h for h in notable if not is_active(h)] if dumping: print(f" 🚨 {('出货中的大户', 'Selling whales')}") for h in dumping[:3]: did = (h.get('twitter_name') or '') or addr_short(h['address']) roles = wallet_roles(h) role_s = "["+"·".join(roles)+"] " if roles else "" print(f" · {role_s}{did} {pct(h['amount_percentage']):.2f}% {('浮盈','pnl')}{(h.get('unrealized_pnl') or 0)*100:+.0f}% {('已卖','sold')} {h.get('sell_tx_count_cur') or 0}x {holding_status(h)}") print() if holding_firm: print(f" 📈 {('持续加仓/未出货', 'Still accumulating / not sold')}") for h in holding_firm[:3]: did = (h.get('twitter_name') or '') or addr_short(h['address']) roles = wallet_roles(h) role_s = "["+"·".join(roles)+"] " if roles else "" print(f" · {role_s}{did} {pct(h['amount_percentage']):.2f}% {('浮盈','pnl')}{(h.get('unrealized_pnl') or 0)*100:+.0f}% {('已买','bought')} {h.get('buy_tx_count_cur') or 0}x") print() if silent_list: silent_pct_val = sum(h['amount_percentage'] for h in silent_list) buy0_cnt = sum(1 for h in silent_list if h.get('buy_tx_count_cur',0)==0) note_str = (("零成本空降为主", "mostly zero-cost airdrop") if buy0_cnt>len(silent_list)//2 else ("持仓未动", "holding without activity")) print(f" 💤 {('静默持仓', 'Silent holders')} {len(silent_list)} {pct(silent_pct_val):.2f}% → {_('抛压低,', 'low pressure, ')}{note_str}") print() print()

── Buying Power ──

── 持仓者购买力 ──

sec6 = ("💰 持仓者购买力", "💰 Holder Buying Power") print(f"━━ {sec6} {'━'*(54-len(sec6))}") print() print(f" {('衡量现有持仓者还有多少子弹可以加仓', 'How much ammo holders have left to add')} {('合计可用余额', 'Total balance')} {usd(total_buying_power)}") print() if zero_wallets: print(f" ⚫ {('零余额', 'Zero balance')} {len(zero_wallets):3d} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(zero_pct_val):.2f}% $0 → {('无加仓能力,可能是分仓小号', 'No buying power, likely sub-wallets')}") if low_wallets: low_total = sum(native_usd(h) for h in low_wallets) print(f" 🟡 {('低(<$200)', 'Low (<$200)')} {len(low_wallets):3d} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(low_pct_val):.2f}% {usd(low_total)}") if mid_wallets: mid_total = sum(native_usd(h) for h in mid_wallets) print(f" 🟠 {('中($200~$1200)', 'Mid ($200~$1200)')} {len(mid_wallets):3d} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(mid_pct_val):.2f}% {usd(mid_total)}") if high_wallets: print(f" 🔴 {('高($1200+)', 'High ($1200+)')} {len(high_wallets):3d} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(high_pct_val):.2f}% {usd(high_total)} → {('可随时加仓', 'can add anytime')}") print() if high_wallets: print(f" ➤ {('高余额钱包', 'High-balance wallets')} {len(high_wallets)} {('个持仓', 'holding')} {pct(high_pct_val):.1f}%{(',', ', ')}{('合计', 'total')} {usd(high_total)} {('可随时加仓', 'ready to add')}") if zero_wallets and zero_pct_val > 0.05: print(f" ➤ {len(zero_wallets)} {('个钱包零余额(持仓 ', 'wallets with zero balance (hold ')}{pct(zero_pct_val):.1f}%{(')', ')')}, {_('无加仓能力,可能是分仓小号', 'no buying power, likely sub-wallets')}") print()
sec6 = ("💰 持仓者购买力", "💰 Holder Buying Power") print(f"━━ {sec6} {'━'*(54-len(sec6))}") print() print(f" {('衡量现有持仓者还有多少子弹可以加仓', 'How much ammo holders have left to add')} {('合计可用余额', 'Total balance')} {usd(total_buying_power)}") print() if zero_wallets: print(f" ⚫ {('零余额', 'Zero balance')} {len(zero_wallets):3d} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(zero_pct_val):.2f}% $0 → {('无加仓能力,可能是分仓小号', 'No buying power, likely sub-wallets')}") if low_wallets: low_total = sum(native_usd(h) for h in low_wallets) print(f" 🟡 {('低(<$200)', 'Low (<$200)')} {len(low_wallets):3d} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(low_pct_val):.2f}% {usd(low_total)}") if mid_wallets: mid_total = sum(native_usd(h) for h in mid_wallets) print(f" 🟠 {('中($200~$1200)', 'Mid ($200~$1200)')} {len(mid_wallets):3d} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(mid_pct_val):.2f}% {usd(mid_total)}") if high_wallets: print(f" 🔴 {('高($1200+)', 'High ($1200+)')} {len(high_wallets):3d} {('个钱包', 'wallets')} {('持仓', 'hold')} {pct(high_pct_val):.2f}% {usd(high_total)} → {('可随时加仓', 'can add anytime')}") print() if high_wallets: print(f" ➤ {('高余额钱包', 'High-balance wallets')} {len(high_wallets)} {('个持仓', 'holding')} {pct(high_pct_val):.1f}%{(',', ', ')}{('合计', 'total')} {usd(high_total)} {('可随时加仓', 'ready to add')}") if zero_wallets and zero_pct_val > 0.05: print(f" ➤ {len(zero_wallets)} {('个钱包零余额(持仓 ', 'wallets with zero balance (hold ')}{pct(zero_pct_val):.1f}%{(')', ')')}, {_('无加仓能力,可能是分仓小号', 'no buying power, likely sub-wallets')}") print()

── Chip Structure ──

── 筹码结构 ──

sec7 = ("📊 筹码结构", "📊 Chip Structure") print(f"━━ {sec7} {'━'*(54-len(sec7))}") print() total_n = len(normal) if total_n > 0: print(f" {('盈利', 'Profit')} {len(profit_w)} ({len(profit_w)/total_n100:.0f}%) {_('亏损', 'Loss')} {len(loss_w)} ({len(loss_w)/total_n100:.0f}%) {('持平', 'Break-even')} {total_n-len(profit_w)-len(loss_w)}") tf_flag = "⚠️" if len(trapped)>30 else "" print(f" {('套牢盘(浮亏>20%)', 'Underwater (>20% loss)')} {len(trapped)} {('持仓', 'hold')} {pct(sum(h['amount_percentage'] for h in trapped)):.2f}% {tf_flag}") print(f" {('平均持仓时长', 'Avg hold duration')} {avg_hold_days:.1f} {_('天', 'days')}") print()
sec7 = ("📊 筹码结构", "📊 Chip Structure") print(f"━━ {sec7} {'━'*(54-len(sec7))}") print() total_n = len(normal) if total_n > 0: print(f" {('盈利', 'Profit')} {len(profit_w)} ({len(profit_w)/total_n100:.0f}%) {_('亏损', 'Loss')} {len(loss_w)} ({len(loss_w)/total_n100:.0f}%) {('持平', 'Break-even')} {total_n-len(profit_w)-len(loss_w)}") tf_flag = "⚠️" if len(trapped)>30 else "" print(f" {('套牢盘(浮亏>20%)', 'Underwater (>20% loss)')} {len(trapped)} {('持仓', 'hold')} {pct(sum(h['amount_percentage'] for h in trapped)):.2f}% {tf_flag}") print(f" {('平均持仓时长', 'Avg hold duration')} {avg_hold_days:.1f} {_('天', 'days')}") print()

── AI Advice ──

── AI 建议 ──

sec8 = ("🤖 AI 建议", "🤖 AI Advice") print(f"━━ {sec8} {'━'*(54-len(sec8))}") print() print(f" {rating_em} {rating_text}") print() if dangers: print(f" {('核心风险', 'Core Risks')}:") for d in dangers: print(f" · {d}") if warns: print(f" {('注意信号', 'Warnings')}:") for w in warns: print(f" · {w}") if goods: print(f" {('积极因素', 'Positives')}:") for g in goods: print(f" · {g}") hf = "🔴" if healthy_ratio<0.3 else ("🟡" if healthy_ratio<0.5 else "🟢") print(f"\n {('健康筹码', 'Healthy chips')} {pct(healthy_ratio):.1f}% {hf} DEX {pct(dex_pct):.1f}% {('不纳入评估', 'excluded from eval')}") print() print(f" {_('关注以下信号,出现则考虑离场:', 'Watch for these exit signals:')}") for sig in exit_signals: print(f" · {sig}") PYEOF
undefined
sec8 = ("🤖 AI 建议", "🤖 AI Advice") print(f"━━ {sec8} {'━'*(54-len(sec8))}") print() print(f" {rating_em} {rating_text}") print() if dangers: print(f" {('核心风险', 'Core Risks')}:") for d in dangers: print(f" · {d}") if warns: print(f" {('注意信号', 'Warnings')}:") for w in warns: print(f" · {w}") if goods: print(f" {('积极因素', 'Positives')}:") for g in goods: print(f" · {g}") hf = "🔴" if healthy_ratio<0.3 else ("🟡" if healthy_ratio<0.5 else "🟢") print(f"\n {('健康筹码', 'Healthy chips')} {pct(healthy_ratio):.1f}% {hf} DEX {pct(dex_pct):.1f}% {('不纳入评估', 'excluded from eval')}") print() print(f" {_('关注以下信号,出现则考虑离场:', 'Watch for these exit signals:')}") for sig in exit_signals: print(f" · {sig}") PYEOF
undefined

Field Reference

字段参考

Holder object key fields

持仓者对象核心字段

FieldTypeMeaning
address
stringWallet address
balance
floatCurrent token balance
amount_percentage
floatFraction of total supply (0–1). Multiply by 100 for %.
usd_value
floatCurrent USD value of holdings
avg_cost
floatAverage buy price per token
unrealized_pnl
floatUnrealized PnL ratio (0.5 = +50%)
unrealized_profit
floatUnrealized PnL in USD
realized_profit
floatRealized PnL in USD
buy_tx_count_cur
intBuy transactions since token creation
sell_tx_count_cur
intSell transactions since token creation
sell_amount_percentage
floatFraction of total buys that have been sold
start_holding_at
intUnix timestamp of first buy
addr_type
int0=normal wallet, 1=burn/dead, 2=DEX/pool
maker_token_tags
list
bundler
,
rat_trader
,
sniper
,
whale
,
top_holder
,
transfer_in
,
dev_team
,
creator
tags
list
smart_degen
,
pump_smart
,
renowned
,
fresh_wallet
,
wash_trader
,
fomo
,
kol
native_balance
stringRaw native token balance (SOL: lamports /1e9; EVM: wei /1e18)
native_transfer
object
{from_address, amount, timestamp}
— how wallet was funded
twitter_name
stringTwitter handle if known
exchange
stringDEX name for pool wallets
字段类型含义
address
string钱包地址
balance
float当前Token余额
amount_percentage
float占总供应量的比例(0–1),乘以100得到百分比
usd_value
float持仓当前的美元价值
avg_cost
float平均买入单价
unrealized_pnl
float未实现盈亏比例(0.5 = +50%)
unrealized_profit
float未实现盈亏的美元金额
realized_profit
float已实现盈亏的美元金额
buy_tx_count_cur
intToken发行后的买入交易次数
sell_tx_count_cur
intToken发行后的卖出交易次数
sell_amount_percentage
float已卖出数量占总买入数量的比例
start_holding_at
int首次买入的Unix时间戳
addr_type
int0=普通钱包, 1=销毁/死地址, 2=DEX/流动性池
maker_token_tags
list
bundler
,
rat_trader
,
sniper
,
whale
,
top_holder
,
transfer_in
,
dev_team
,
creator
tags
list
smart_degen
,
pump_smart
,
renowned
,
fresh_wallet
,
wash_trader
,
fomo
,
kol
native_balance
string原生Token的原始余额(SOL: lamports,需除以1e9;EVM: wei,需除以1e18)
native_transfer
object
{from_address, amount, timestamp}
— 钱包的资金来源信息
twitter_name
string已知的Twitter账号
exchange
string流动性池钱包对应的DEX名称

Created-tokens response fields

发行Token响应字段

FieldMeaning
inner_count
Unmigrated token count
open_count
Migrated token count
tokens[].market_cap
Current market cap in USD
tokens[].is_open
true = migrated
creator_ath_info.ath_mc
All-time high MC across all created tokens
creator_ath_info.ath_token
Token address of the ATH token
creator_ath_info.token_symbol
Symbol of the ATH token
字段含义
inner_count
未迁移的Token数量
open_count
已迁移的Token数量
tokens[].market_cap
当前市值(美元)
tokens[].is_open
true = 已迁移
creator_ath_info.ath_mc
所有发行Token中的历史最高市值
creator_ath_info.ath_token
达到历史最高市值的Token地址
creator_ath_info.token_symbol
达到历史最高市值的Token符号

Rating Standard

评级标准

Entry timing pressure (批次浮盈/出货) does NOT affect the overall rating — it only affects section display.
Rating (ZH)Rating (EN)EmojiCondition
不建议买Not Recommended🔴Any: rat traders >10% / largest wallet >15% / dev sock puppet
谨慎参与Caution⚠️≥2 of: Dev still holding / airdrop >15% / risk wallets >30% / linked >10%
可轻仓Light Position🟡Exactly 1 of above warns
正常参与NormalNone of the above
入场时机压力(批次浮盈/出货情况)不影响整体评级,仅影响对应章节的展示。
中文评级英文评级表情条件
不建议买Not Recommended🔴满足任一条件:老鼠仓占比>10% / 最大单钱包占比>15% / Dev使用马甲持仓
谨慎参与Caution⚠️满足至少2项:Dev仍持仓 / 空降筹码占比>15% / 风险钱包占比>30% / 关联钱包占比>10%
可轻仓Light Position🟡仅满足上述1项警告
正常参与Normal不满足上述任何条件

Supported Chains

支持的链

sol
,
bsc
,
base
,
eth
,
robinhood
sol
,
bsc
,
base
,
eth
,
robinhood

Notes

注意事项

  • balance >= 1
    threshold avoids dust false positives when identifying dev holdings
  • SOL
    native_balance
    is in lamports (÷1e9); EVM
    native_balance
    is in wei (÷1e18)
  • total_supply
    is estimated as the median of
    balance / amount_percentage
    across normal wallets
  • cur_price
    is estimated as the median of
    usd_value / balance
    across normal wallets
  • Top5 displays Twitter name when available; else
    first4...last4
    format
  • balance >= 1
    的阈值用于识别Dev持仓时避免小额粉尘余额的误判
  • SOL的
    native_balance
    单位为lamports(需÷1e9);EVM的
    native_balance
    单位为wei(需÷1e18)
  • total_supply
    通过普通钱包的
    balance / amount_percentage
    的中位数估算
  • cur_price
    通过普通钱包的
    usd_value / balance
    的中位数估算
  • Top5展示优先使用Twitter名称,否则使用
    前4位...后4位
    格式