Initial commit: coin-hunter skill
This commit is contained in:
296
SKILL.md
Normal file
296
SKILL.md
Normal file
@@ -0,0 +1,296 @@
|
||||
---
|
||||
name: coin-hunter
|
||||
description: Hunt, triage, and compare speculative crypto coins — especially meme coins, 妖币-style runners, fake-hype pumps, and possible rug/scam setups. Use when a user wants to actively search for coins with breakout potential, rank a shortlist, ask whether a coin still has "妖性", or check whether a token looks late, fragile, manipulated, or likely to be a scam.
|
||||
---
|
||||
|
||||
# Coin Hunter
|
||||
|
||||
## Overview
|
||||
|
||||
Use this skill to help a user search for and judge **high-volatility crypto setups** without pretending certainty.
|
||||
|
||||
Default buckets:
|
||||
- **candidate runner** — has ingredients for further speculative expansion
|
||||
- **watch-only / incomplete** — interesting, but not clean enough yet
|
||||
- **late / overheated** — may still move, but entry quality is already poor
|
||||
- **avoid / scam-risk** — liquidity, distribution, credibility, or structure is too weak
|
||||
|
||||
Frame the work as **speculative pattern recognition**, not investment advice.
|
||||
|
||||
## Core rule
|
||||
|
||||
Judge a coin by **attention + liquidity + distribution + timing** first. Narrative matters, but only when it can attract and hold money.
|
||||
|
||||
A technically weak project can still become a runner. A sophisticated-looking project can still be dead money.
|
||||
|
||||
## Supported request types
|
||||
|
||||
Use this skill for four common modes:
|
||||
- **single-coin triage** — "look at this coin"
|
||||
- **active discovery** — "find me coins that could become 妖币"
|
||||
- **shortlist ranking** — "which of these 5 is most interesting"
|
||||
- **scam / rug check** — "is this coin just fake hype"
|
||||
|
||||
If the request is broad, ask at most **one compact clarifying question**. Prefer:
|
||||
- chain
|
||||
- theme / narrative
|
||||
- risk level
|
||||
- whether the user accepts microcaps or wants only reasonably tradable names
|
||||
|
||||
If no preference is given, default to: **liquid speculative candidates, not ultra-illiquid microcaps**.
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Identify the mode
|
||||
|
||||
Decide whether the user wants:
|
||||
- discovery
|
||||
- triage
|
||||
- comparison
|
||||
- scam-check
|
||||
|
||||
Then bias the workflow accordingly.
|
||||
|
||||
### 2. Choose the data path
|
||||
|
||||
Use **structured market data first** when available. Use web search to discover names and collect context, not as the only source of truth.
|
||||
|
||||
Preferred source order:
|
||||
- **Bybit** for real-time-ish price, 24h turnover, and tradability on a major venue
|
||||
- **DexScreener** for meme-coin pair discovery, DEX liquidity, and small-cap flow
|
||||
- **Birdeye** for Solana token activity and confirmation
|
||||
- **CoinGecko** for market-cap, rank, and metadata cross-check
|
||||
- **web_search** for discovery, narratives, and scam-discussion context
|
||||
|
||||
Private user state must live outside the skill directory under `~/.coin-hunter/`, not inside `skills/coin-hunter/`.
|
||||
Read `references/provider-playbook.md` when choosing which source to trust first.
|
||||
Read `references/user-data-layout.md` when adding or updating personal accounts, positions, watchlists, or notes.
|
||||
Use `scripts/market_probe.py` for deterministic provider lookups.
|
||||
Use `scripts/init_user_state.py` to initialize the private user-data directory.
|
||||
|
||||
### 3. Discovery mode: build a candidate list
|
||||
|
||||
When the user wants active search rather than analysis of a known ticker, use public web sources to build a shortlist.
|
||||
|
||||
Look for evidence of:
|
||||
- rising attention
|
||||
- listing or venue expansion
|
||||
- narrative/theme alignment
|
||||
- market-cap and liquidity context
|
||||
- breakout discussion or unusual participation
|
||||
|
||||
Useful search patterns include:
|
||||
- `<theme> meme coin trending`
|
||||
- `<chain> meme coin watchlist`
|
||||
- `new meme coin listed`
|
||||
- `<coin> market cap liquidity`
|
||||
- `<coin> holders tokenomics`
|
||||
- `<coin> rug risk`
|
||||
|
||||
Do not trust a single source or a single viral thread. Build the list first, then vet the names.
|
||||
|
||||
Read `references/search-workflow.md` for the detailed discovery flow.
|
||||
|
||||
### 4. Triage mode: score the coin on six dimensions
|
||||
|
||||
Assess each coin qualitatively across these dimensions.
|
||||
|
||||
#### A. Narrative fit
|
||||
Ask:
|
||||
- Is the story attached to a live theme?
|
||||
- Is the idea easy to repeat in one sentence?
|
||||
- Does the symbol / meme / framing have social spread potential?
|
||||
|
||||
Strong examples:
|
||||
- obvious meme identity
|
||||
- attached to a live chain or hot sector
|
||||
- easy cultural hook
|
||||
|
||||
Weak examples:
|
||||
- vague utility story
|
||||
- no memorable angle
|
||||
- cold or stale narrative
|
||||
|
||||
#### B. Attention acceleration
|
||||
Ask:
|
||||
- Is visibility rising now?
|
||||
- Is the coin spreading beyond its original niche?
|
||||
- Are larger accounts, aggregators, or trading communities starting to notice it?
|
||||
|
||||
Treat **acceleration** as more important than absolute popularity.
|
||||
|
||||
#### C. Liquidity quality
|
||||
Ask:
|
||||
- Can a normal user realistically enter and exit?
|
||||
- Is volume believable relative to market cap and attention?
|
||||
- Are spreads or venue quality obviously problematic?
|
||||
|
||||
If the user can probably buy but may not be able to exit cleanly, score this harshly.
|
||||
|
||||
#### D. Distribution / holder risk
|
||||
Ask:
|
||||
- Is ownership too concentrated?
|
||||
- Are deployer or team wallets still dangerous?
|
||||
- Is there an obvious unlock or dump overhang?
|
||||
|
||||
Ugly distribution does not automatically kill a trade, but it makes the setup fragile.
|
||||
|
||||
#### E. Timing / chart state
|
||||
Ask:
|
||||
- Is it emerging from a base or already vertical?
|
||||
- Has participation expanded recently?
|
||||
- Do pullbacks hold, or do they collapse?
|
||||
|
||||
Prefer:
|
||||
- fresh breakout from longer consolidation
|
||||
- early or mid-stage expansion
|
||||
- resilient retraces
|
||||
|
||||
Be cautious when:
|
||||
- it already went parabolic
|
||||
- volume fades after the first mania burst
|
||||
- price action is mostly wick-and-dump behavior
|
||||
|
||||
#### F. Rug / scam risk
|
||||
Check for:
|
||||
- fake partnerships or fake listing claims
|
||||
- unverifiable team paired with aggressive promotion
|
||||
- suspicious contract / public warning signals
|
||||
- impossible tokenomics promises
|
||||
- unverified liquidity-lock claims
|
||||
- nothing but shill posts and no independent discussion
|
||||
|
||||
One severe scam signal can outweigh several bullish ones.
|
||||
Read `references/scam-signals.md` when the user specifically asks about rugs, scams, fake hype, manipulation, or exit-liquidity bait.
|
||||
|
||||
### 5. Classify the result
|
||||
|
||||
Use these buckets:
|
||||
|
||||
#### Candidate runner
|
||||
Use when most are true:
|
||||
- narrative is live
|
||||
- attention is accelerating
|
||||
- liquidity is usable
|
||||
- timing is not obviously exhausted
|
||||
- no fatal scam / exit-risk signal is present
|
||||
|
||||
#### Watch-only / incomplete
|
||||
Use when:
|
||||
- something is interesting, but evidence is incomplete
|
||||
- narrative is decent but timing is unclear
|
||||
- liquidity or distribution is acceptable but not clean
|
||||
- it deserves monitoring more than action
|
||||
|
||||
#### Late / overheated
|
||||
Use when:
|
||||
- the move is already widely noticed
|
||||
- chart is extended or near blow-off behavior
|
||||
- upside may remain, but entry quality is poor
|
||||
- new buyers are at risk of becoming exit liquidity
|
||||
|
||||
#### Avoid / scam-risk
|
||||
Use when:
|
||||
- liquidity quality is bad
|
||||
- exit risk is high
|
||||
- holder concentration is dangerous
|
||||
- legitimacy claims are weak or fake
|
||||
- the setup feels more fabricated than organic
|
||||
|
||||
## Provider execution patterns
|
||||
|
||||
### Known tradable coin
|
||||
If the user gives a Bybit-listed ticker or asks for current price/tradability:
|
||||
1. run `python3 scripts/market_probe.py bybit-ticker <SYMBOL>`
|
||||
2. optionally run `python3 scripts/market_probe.py bybit-klines <SYMBOL> --interval 60 --limit 10`
|
||||
3. cross-check with CoinGecko when market-cap context matters
|
||||
|
||||
### Meme / 妖币 discovery
|
||||
If the user wants runners, meme coins, or small-cap candidates:
|
||||
1. use `web_search` to gather names
|
||||
2. run `python3 scripts/market_probe.py dex-search <name>` for the strongest candidates
|
||||
3. if Solana, run Birdeye when API access is configured
|
||||
4. use CoinGecko to verify market-cap and ranking
|
||||
5. only use Bybit if the coin is also on a major CEX
|
||||
|
||||
### Birdeye requirement
|
||||
`market_probe.py birdeye-token <address>` requires `BIRDEYE_API_KEY` in the environment. If it is not configured, say so briefly and continue with DexScreener + CoinGecko + web search.
|
||||
|
||||
### Private portfolio state
|
||||
If the user wants account, position, watchlist, or thesis tracking for coin-hunter:
|
||||
1. initialize `~/.coin-hunter/` with `python3 scripts/init_user_state.py`
|
||||
2. store private data only there
|
||||
3. never place personal holdings inside the skill folder
|
||||
4. treat the skill folder as logic only, and the user-data directory as state only
|
||||
|
||||
## Output style
|
||||
|
||||
Default to **compact, decision-first** answers.
|
||||
|
||||
For a single coin, include:
|
||||
- **Verdict**
|
||||
- **Radar score** — use the 0-12 checklist when evidence is sufficient
|
||||
- **Why it could run** — 2-4 bullets
|
||||
- **Why it could fail** — 2-4 bullets
|
||||
- **What confirms strength**
|
||||
- **What kills the thesis**
|
||||
- **Risk line** — clearly state this is speculative, not investment advice
|
||||
|
||||
For multiple coins:
|
||||
1. rank the shortlist
|
||||
2. mark each as candidate runner / watch-only / late / avoid
|
||||
3. state the main attraction and main flaw for each
|
||||
|
||||
Prefer bullets, short sections, and hard judgments over long essays.
|
||||
Use `references/output-templates.md` when you want a reusable answer skeleton.
|
||||
|
||||
## Practical heuristics
|
||||
|
||||
### Often bullish for speculative expansion
|
||||
- the meme or story is instantly repeatable
|
||||
- attention is accelerating, not just present
|
||||
- volume expands with the move
|
||||
- pullbacks are bought
|
||||
- exchange accessibility improves
|
||||
- more mainstream crypto accounts begin to mention it
|
||||
|
||||
### Often a sign it is late
|
||||
- everyone is already talking about it
|
||||
- the chart has been vertical for days
|
||||
- promotion is everywhere after the main move already happened
|
||||
- price keeps spiking while structure gets messier
|
||||
|
||||
### Often a sign to avoid
|
||||
- no trustworthy liquidity information
|
||||
- suspicious ownership concentration
|
||||
- clearly manufactured chart behavior
|
||||
- incoherent or constantly shifting explanation
|
||||
- obviously botted or repetitive social activity
|
||||
|
||||
## What not to do
|
||||
|
||||
- Do not describe a coin as safe.
|
||||
- Do not confuse a polished whitepaper with breakout potential.
|
||||
- Do not imply expected returns.
|
||||
- Do not recommend leverage.
|
||||
- Do not ignore slippage and exit risk.
|
||||
- Do not push microcaps on beginners unless the user explicitly asks for extreme risk.
|
||||
|
||||
## Optional deeper pass
|
||||
|
||||
If the user wants more depth, expand in this order:
|
||||
1. narrative and timing
|
||||
2. liquidity and market structure
|
||||
3. holder / tokenomics risk
|
||||
4. why it could become a runner
|
||||
5. why it probably will not
|
||||
6. watch triggers
|
||||
|
||||
## References
|
||||
|
||||
Read `references/provider-playbook.md` for source selection and provider roles.
|
||||
Read `references/user-data-layout.md` for private state layout under `~/.coin-hunter/`.
|
||||
Read `references/radar-checklist.md` for a quick scoring framework.
|
||||
Read `references/search-workflow.md` for active discovery.
|
||||
Read `references/output-templates.md` for compact response structure.
|
||||
Read `references/scam-signals.md` for sharper scam / fake-hype judgment.
|
||||
71
references/output-templates.md
Normal file
71
references/output-templates.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Output Templates
|
||||
|
||||
Use these templates to keep answers crisp and decision-first.
|
||||
|
||||
## Single-coin quick triage
|
||||
|
||||
**Verdict:** candidate runner | late / overheated | avoid / scam-risk
|
||||
**Radar score:** X/12
|
||||
**Spec setup quality:** high | medium | low
|
||||
|
||||
**Why it could run**
|
||||
- ...
|
||||
- ...
|
||||
- ...
|
||||
|
||||
**Why it could fail**
|
||||
- ...
|
||||
- ...
|
||||
- ...
|
||||
|
||||
**What confirms strength**
|
||||
- ...
|
||||
- ...
|
||||
|
||||
**What kills the thesis**
|
||||
- ...
|
||||
- ...
|
||||
|
||||
**Risk note:** This is speculative pattern recognition, not investment advice.
|
||||
|
||||
## Multi-coin shortlist
|
||||
|
||||
### 1. <coin>
|
||||
- **Verdict:**
|
||||
- **Radar score:** X/12
|
||||
- **Why it made the cut:**
|
||||
- **Biggest flaw:**
|
||||
|
||||
### 2. <coin>
|
||||
- **Verdict:**
|
||||
- **Radar score:** X/12
|
||||
- **Why it made the cut:**
|
||||
- **Biggest flaw:**
|
||||
|
||||
### 3. <coin>
|
||||
- **Verdict:**
|
||||
- **Radar score:** X/12
|
||||
- **Why it made the cut:**
|
||||
- **Biggest flaw:**
|
||||
|
||||
**Bottom line**
|
||||
- Most interesting now:
|
||||
- Worth watching only:
|
||||
- Avoid first:
|
||||
|
||||
## Scam-check format
|
||||
|
||||
**Verdict:** likely tradable speculation | fragile / high-risk | avoid / scam-risk
|
||||
|
||||
**Main warning signs**
|
||||
- ...
|
||||
- ...
|
||||
|
||||
**Any redeeming signs**
|
||||
- ...
|
||||
- ...
|
||||
|
||||
**Decision**
|
||||
- what a cautious user should do next
|
||||
|
||||
**Risk note:** Absence of red flags is not proof of safety.
|
||||
92
references/provider-playbook.md
Normal file
92
references/provider-playbook.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Provider Playbook
|
||||
|
||||
Use this reference when the user wants fresher crypto market data instead of relying only on web search.
|
||||
|
||||
## Source roles
|
||||
|
||||
### Bybit
|
||||
Use for:
|
||||
- real-time-ish price
|
||||
- 24h turnover / volume
|
||||
- tradability check
|
||||
- kline context for listed pairs
|
||||
|
||||
Prefer Bybit first when the coin has a clear CEX symbol like `BTCUSDT`, `ETHUSDT`, `BONKUSDT`, etc.
|
||||
|
||||
### DexScreener
|
||||
Use for:
|
||||
- meme-coin discovery
|
||||
- DEX liquidity / pair context
|
||||
- chain and pool identification
|
||||
- faster read on small-cap or newly-hot coins
|
||||
|
||||
Prefer DexScreener when:
|
||||
- the coin is meme-heavy
|
||||
- it may not be on major CEXs
|
||||
- you need pair/liquidity context more than exchange execution context
|
||||
|
||||
### Birdeye
|
||||
Use for:
|
||||
- Solana meme-coin discovery
|
||||
- Solana token activity and pair context
|
||||
- confirming whether a Solana coin has genuine participation
|
||||
|
||||
Birdeye is especially useful when Solana names appear early in discovery.
|
||||
|
||||
### CoinGecko
|
||||
Use for:
|
||||
- market-cap cross-check
|
||||
- ranking / metadata / basic overview
|
||||
- fallback verification when exchange or DEX data is messy
|
||||
|
||||
Use CoinGecko to sanity-check whether the coin is a real market object with broad coverage.
|
||||
|
||||
## Recommended order
|
||||
|
||||
### For a known Bybit-listed coin
|
||||
1. Bybit
|
||||
2. CoinGecko
|
||||
3. DexScreener if meme angle matters
|
||||
|
||||
### For a meme / 妖币 candidate
|
||||
1. DexScreener
|
||||
2. Birdeye if Solana
|
||||
3. CoinGecko
|
||||
4. Bybit only if it is also listed there
|
||||
|
||||
### For discovery mode
|
||||
1. web_search to gather candidate names
|
||||
2. DexScreener to confirm pair/liquidity reality
|
||||
3. Birdeye for Solana candidates
|
||||
4. CoinGecko for market-cap verification
|
||||
5. Bybit to see whether the name graduated into a major tradable venue
|
||||
|
||||
## What each source answers
|
||||
|
||||
- **Bybit** → "Can I trade it on a major venue, and what does the market look like right now?"
|
||||
- **DexScreener** → "Does it actually have live DEX flow and liquidity?"
|
||||
- **Birdeye** → "Is the Solana on-chain activity real enough to care about?"
|
||||
- **CoinGecko** → "How big is it, and is it broadly recognized?"
|
||||
|
||||
## Practical rule
|
||||
|
||||
Do not make conviction from a single source.
|
||||
|
||||
For high-risk coins, prefer at least two independent checks:
|
||||
- one trading/liquidity source
|
||||
- one metadata/market-cap source
|
||||
|
||||
## Token identity hygiene
|
||||
|
||||
DexScreener search can return clones, stale pairs, and same-name distractions.
|
||||
|
||||
Before treating a result as the real target, prefer the pair that has:
|
||||
- the strongest 24h volume and usable liquidity
|
||||
- a market cap / FDV that roughly matches CoinGecko or other broad coverage sources
|
||||
- a chain and venue context that fits the narrative you are checking
|
||||
|
||||
If search results show multiple same-name tokens, explicitly say which contract or pair you are treating as the primary one.
|
||||
|
||||
## Script usage
|
||||
|
||||
Use `scripts/market_probe.py` for deterministic lookups instead of redoing provider URLs by hand.
|
||||
63
references/radar-checklist.md
Normal file
63
references/radar-checklist.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Coin Radar Checklist
|
||||
|
||||
Use this checklist for fast triage.
|
||||
|
||||
## Fast scorecard
|
||||
|
||||
Score each dimension from 0 to 2.
|
||||
|
||||
- **Narrative**
|
||||
- 0 = no clear story or hook
|
||||
- 1 = understandable but weak
|
||||
- 2 = strong, simple, contagious
|
||||
|
||||
- **Attention acceleration**
|
||||
- 0 = stagnant / invisible
|
||||
- 1 = niche chatter rising
|
||||
- 2 = clearly spreading beyond niche
|
||||
|
||||
- **Liquidity**
|
||||
- 0 = poor / suspicious / hard to exit
|
||||
- 1 = usable but thin
|
||||
- 2 = solid enough for speculation
|
||||
|
||||
- **Distribution quality**
|
||||
- 0 = dangerous concentration
|
||||
- 1 = somewhat fragile
|
||||
- 2 = acceptable for a speculative trade
|
||||
|
||||
- **Timing / chart state**
|
||||
- 0 = broken or exhausted
|
||||
- 1 = unclear
|
||||
- 2 = early-to-mid expansion setup
|
||||
|
||||
- **Scam-risk cleanliness**
|
||||
- 0 = obvious warnings
|
||||
- 1 = mixed / uncertain
|
||||
- 2 = no major public red flags found
|
||||
|
||||
## Quick interpretation
|
||||
|
||||
- **10-12** → strong speculative candidate; timing still matters
|
||||
- **7-9** → watchlist material; interesting but incomplete
|
||||
- **4-6** → weak; only for high-risk curiosity
|
||||
- **0-3** → avoid
|
||||
|
||||
## Compact answer template
|
||||
|
||||
- **Verdict:**
|
||||
- **Radar score:** X/12
|
||||
- **Why it’s interesting:**
|
||||
- **Main flaws:**
|
||||
- **What would confirm it:**
|
||||
- **What would invalidate it:**
|
||||
- **Risk note:** speculative only, not investment advice
|
||||
|
||||
## Hard-stop red flags
|
||||
|
||||
If any of these appear, strongly consider overriding the score to avoid:
|
||||
- obvious inability to exit
|
||||
- strong public rug warnings
|
||||
- fake or unverifiable listing/partnership claims
|
||||
- extreme wallet concentration with live dump risk
|
||||
- chart structure that looks purely manipulated
|
||||
109
references/scam-signals.md
Normal file
109
references/scam-signals.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Scam / Fake-Hype Signals
|
||||
|
||||
Use this reference when a user asks whether a coin is a rug, scam, fake narrative pump, or suspicious meme coin.
|
||||
|
||||
## Goal
|
||||
|
||||
Separate three different bad cases:
|
||||
- **obvious scam-risk** — high chance of rug, manipulation, or fabricated legitimacy
|
||||
- **fake-hype / low-quality pump** — may trade, but the story is mostly noise and exit liquidity risk is high
|
||||
- **messy but tradable** — ugly structure, but not enough evidence to call it a scam
|
||||
|
||||
Do not collapse all weak coins into "scam." Be precise.
|
||||
|
||||
## Primary red flags
|
||||
|
||||
### 1. Liquidity illusion
|
||||
Warning signs:
|
||||
- the coin appears tradable, but exits are unclear
|
||||
- volume looks large relative to real attention
|
||||
- spreads are erratic or suspiciously wide
|
||||
- price moves hard on small visible participation
|
||||
|
||||
Interpretation:
|
||||
- if buyers can enter more easily than they can exit, treat this as a severe warning
|
||||
|
||||
### 2. Holder concentration risk
|
||||
Warning signs:
|
||||
- a few wallets dominate supply
|
||||
- deployer/team wallets remain powerful
|
||||
- clustered wallets look related
|
||||
- unlock or dump overhang seems obvious
|
||||
|
||||
Interpretation:
|
||||
- concentration does not automatically mean scam, but it makes the coin structurally fragile
|
||||
- if concentration is extreme and active, classify closer to avoid / scam-risk
|
||||
|
||||
### 3. Legitimacy theater
|
||||
Warning signs:
|
||||
- loud claims of partnerships with no verifiable source
|
||||
- fake exchange-listing rumors
|
||||
- website looks polished but contains no falsifiable specifics
|
||||
- team bios are vague, recycled, or unverifiable
|
||||
- social posts overpromise and under-document
|
||||
|
||||
Interpretation:
|
||||
- fake credibility signals are often more important than weak fundamentals
|
||||
|
||||
### 4. Social proof distortion
|
||||
Warning signs:
|
||||
- comments feel repetitive or botted
|
||||
- follower count is high but engagement quality is low
|
||||
- shill accounts post identical talking points
|
||||
- the project feels ubiquitous inside its own bubble but invisible elsewhere
|
||||
|
||||
Interpretation:
|
||||
- hype quality matters more than hype quantity
|
||||
|
||||
### 5. Chart manipulation smell
|
||||
Warning signs:
|
||||
- repeated long wicks without stable follow-through
|
||||
- random explosive candles with no broader market pickup
|
||||
- price repeatedly returns to the same area after dramatic spikes
|
||||
- pattern looks designed to bait breakout traders
|
||||
|
||||
Interpretation:
|
||||
- manufactured excitement often looks different from organic expansion
|
||||
|
||||
## Secondary warning signs
|
||||
|
||||
These do not prove scam by themselves, but they weaken the case:
|
||||
- narrative changes every few days
|
||||
- too many sectors/themes stapled together
|
||||
- tokenomics explanation is confusing on purpose
|
||||
- everything depends on one influencer wave
|
||||
- no credible venue improvement despite heavy promotion
|
||||
|
||||
## Useful distinctions
|
||||
|
||||
### Scam-risk
|
||||
Use when one or more of these are true:
|
||||
- severe exit/liquidity concerns
|
||||
- strong public warnings from multiple independent places
|
||||
- fabricated legitimacy claims look credible
|
||||
- wallet concentration plus active dump risk is severe
|
||||
|
||||
### Fake-hype / low-quality pump
|
||||
Use when:
|
||||
- the coin may still trade, but most of the fuel is shallow attention
|
||||
- quality of discussion is poor
|
||||
- market structure looks weak
|
||||
- timing is bad and late buyers are likely exit liquidity
|
||||
|
||||
### Messy but tradable
|
||||
Use when:
|
||||
- structure is ugly, but not enough to call scam
|
||||
- there is still credible liquidity and real attention
|
||||
- risk is high, but the market is not obviously fake
|
||||
|
||||
## Output guidance
|
||||
|
||||
When scam risk is part of the analysis, include:
|
||||
- **Suspicion level:** low / medium / high
|
||||
- **Main red flags:** 2-5 bullets
|
||||
- **What would reduce suspicion:** specific evidence, not vibes
|
||||
- **Bottom line:** tradable speculation / watch-only / avoid
|
||||
|
||||
## Hard override rule
|
||||
|
||||
Even if the narrative and attention look strong, classify as **avoid / scam-risk** when exit risk or fabricated legitimacy is severe enough.
|
||||
90
references/search-workflow.md
Normal file
90
references/search-workflow.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Search Workflow
|
||||
|
||||
Use this workflow when the user wants you to proactively discover meme-coin / 妖币 candidates instead of analyzing a known ticker.
|
||||
|
||||
## Goal
|
||||
|
||||
Produce a shortlist with enough evidence to answer:
|
||||
- what deserves attention now
|
||||
- what is merely noisy
|
||||
- what should be avoided
|
||||
|
||||
## Default search strategy
|
||||
|
||||
Unless the user specifies otherwise, search for **liquid speculative candidates** first and avoid ultra-microcaps.
|
||||
|
||||
Run search in this order:
|
||||
|
||||
1. **Theme scan**
|
||||
- Search current meme-coin themes by chain or narrative
|
||||
- Examples:
|
||||
- `Solana meme coins trending`
|
||||
- `Base meme coin watchlist`
|
||||
- `AI meme coin trending`
|
||||
- `new meme coin listed today`
|
||||
|
||||
2. **Candidate extraction**
|
||||
- Pull out repeated names that appear across multiple sources
|
||||
- Prefer coins that appear in both market-oriented and community-oriented sources
|
||||
|
||||
3. **Candidate verification**
|
||||
- For each candidate, search:
|
||||
- `<coin> market cap liquidity`
|
||||
- `<coin> holders tokenomics`
|
||||
- `<coin> rug risk`
|
||||
- `<coin> listed on exchange`
|
||||
|
||||
4. **Cross-check timing**
|
||||
- Search whether the coin is already broadly saturated:
|
||||
- `<coin> trending X`
|
||||
- `<coin> breakout volume`
|
||||
- `<coin> price surge`
|
||||
- If it is already universally discussed, consider classifying it as late rather than early
|
||||
|
||||
## Source preference
|
||||
|
||||
Prefer a mix of:
|
||||
- credible exchange announcements or listing pages
|
||||
- market data summaries
|
||||
- crypto news aggregation
|
||||
- community/trading discussion summaries
|
||||
|
||||
Do not rely entirely on project websites or obvious promotion pages.
|
||||
|
||||
## Discovery rules
|
||||
|
||||
### Good candidate signs during search
|
||||
- name appears repeatedly across different sources
|
||||
- tied to a live narrative or active chain
|
||||
- discussion suggests recent acceleration, not just old fame
|
||||
- accessible enough that the user can realistically trade it
|
||||
|
||||
### Weak candidate signs during search
|
||||
- only appears in promotional pages
|
||||
- only appears on tiny venues
|
||||
- no independent discussion or market data context
|
||||
- most results are already about an explosive move that happened days ago
|
||||
|
||||
## Shortlist size
|
||||
|
||||
Default to **3-5 candidates**.
|
||||
|
||||
If the search returns many names:
|
||||
- keep the most repeated
|
||||
- keep the ones with the clearest narrative
|
||||
- remove obviously illiquid or scammy names first
|
||||
|
||||
## Output shape for discovery mode
|
||||
|
||||
For each shortlisted candidate include:
|
||||
- ticker / name
|
||||
- chain / venue context if known
|
||||
- why it entered the shortlist
|
||||
- biggest risk
|
||||
- tentative bucket: candidate runner / watch-only / avoid
|
||||
|
||||
Then give a final rank order.
|
||||
|
||||
## Notes
|
||||
|
||||
When evidence is weak, say so. Discovery mode is for narrowing attention, not pretending certainty.
|
||||
143
references/user-data-layout.md
Normal file
143
references/user-data-layout.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# User Data Layout
|
||||
|
||||
Store private coin-hunter data outside the skill directory.
|
||||
|
||||
## Root directory
|
||||
|
||||
Use:
|
||||
|
||||
```text
|
||||
~/.coin-hunter/
|
||||
```
|
||||
|
||||
This keeps personal accounts, positions, and watchlists out of packaged skill artifacts.
|
||||
|
||||
## Layout
|
||||
|
||||
```text
|
||||
~/.coin-hunter/
|
||||
├── config.json
|
||||
├── accounts.json
|
||||
├── positions.json
|
||||
├── watchlist.json
|
||||
├── notes.json
|
||||
└── cache/
|
||||
```
|
||||
|
||||
## File roles
|
||||
|
||||
### config.json
|
||||
Store user-level defaults.
|
||||
|
||||
Suggested fields:
|
||||
- `default_exchange`
|
||||
- `default_quote_currency`
|
||||
- `timezone`
|
||||
- `preferred_chains`
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"default_exchange": "bybit",
|
||||
"default_quote_currency": "USDT",
|
||||
"timezone": "Asia/Shanghai",
|
||||
"preferred_chains": ["solana", "base"]
|
||||
}
|
||||
```
|
||||
|
||||
### accounts.json
|
||||
Store exchange accounts and balances.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"accounts": [
|
||||
{
|
||||
"id": "bybit-main",
|
||||
"exchange": "bybit",
|
||||
"label": "Bybit Main",
|
||||
"currency": "USDT",
|
||||
"cash_balance": 0,
|
||||
"available_cash": 0,
|
||||
"updated_at": null,
|
||||
"note": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### positions.json
|
||||
Store coin positions.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"positions": [
|
||||
{
|
||||
"account_id": "bybit-main",
|
||||
"symbol": "BTCUSDT",
|
||||
"base_asset": "BTC",
|
||||
"quote_asset": "USDT",
|
||||
"market_type": "spot",
|
||||
"quantity": 0,
|
||||
"avg_cost": 0,
|
||||
"opened_at": null,
|
||||
"updated_at": null,
|
||||
"note": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### watchlist.json
|
||||
Store watched coins.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"watchlist": [
|
||||
{
|
||||
"symbol": "FARTCOIN",
|
||||
"chain": "solana",
|
||||
"contract_address": null,
|
||||
"source": "manual",
|
||||
"status": "watching",
|
||||
"added_at": null,
|
||||
"note": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### notes.json
|
||||
Store discretionary notes and thesis fragments.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"notes": [
|
||||
{
|
||||
"symbol": "FARTCOIN",
|
||||
"title": "Why this stays on radar",
|
||||
"body": "Good liquidity, strong meme spread, only for high-risk observation.",
|
||||
"updated_at": null
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### cache/
|
||||
Store disposable API results or normalized snapshots. Never treat this as source-of-truth portfolio state.
|
||||
|
||||
## Rules
|
||||
|
||||
- Keep personal data only under `~/.coin-hunter/`
|
||||
- Never write personal account or position data into `skills/coin-hunter/`
|
||||
- Treat `cache/` as disposable
|
||||
- Prefer stable IDs for accounts like `bybit-main`
|
||||
- For meme coins, include `chain` and `contract_address` when known
|
||||
63
scripts/init_user_state.py
Normal file
63
scripts/init_user_state.py
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path.home() / ".coin-hunter"
|
||||
CACHE_DIR = ROOT / "cache"
|
||||
|
||||
|
||||
def now_iso():
|
||||
return datetime.now(timezone.utc).replace(microsecond=0).isoformat()
|
||||
|
||||
|
||||
def ensure_file(path: Path, payload: dict):
|
||||
if path.exists():
|
||||
return False
|
||||
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
ROOT.mkdir(parents=True, exist_ok=True)
|
||||
CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
created = []
|
||||
ts = now_iso()
|
||||
|
||||
templates = {
|
||||
ROOT / "config.json": {
|
||||
"default_exchange": "bybit",
|
||||
"default_quote_currency": "USDT",
|
||||
"timezone": "Asia/Shanghai",
|
||||
"preferred_chains": ["solana", "base"],
|
||||
"created_at": ts,
|
||||
"updated_at": ts,
|
||||
},
|
||||
ROOT / "accounts.json": {
|
||||
"accounts": []
|
||||
},
|
||||
ROOT / "positions.json": {
|
||||
"positions": []
|
||||
},
|
||||
ROOT / "watchlist.json": {
|
||||
"watchlist": []
|
||||
},
|
||||
ROOT / "notes.json": {
|
||||
"notes": []
|
||||
},
|
||||
}
|
||||
|
||||
for path, payload in templates.items():
|
||||
if ensure_file(path, payload):
|
||||
created.append(str(path))
|
||||
|
||||
print(json.dumps({
|
||||
"root": str(ROOT),
|
||||
"created": created,
|
||||
"cache_dir": str(CACHE_DIR),
|
||||
}, ensure_ascii=False, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
243
scripts/market_probe.py
Normal file
243
scripts/market_probe.py
Normal file
@@ -0,0 +1,243 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
DEFAULT_TIMEOUT = 20
|
||||
|
||||
|
||||
def fetch_json(url, headers=None, timeout=DEFAULT_TIMEOUT):
|
||||
merged_headers = {
|
||||
"Accept": "application/json",
|
||||
"User-Agent": "Mozilla/5.0 (compatible; OpenClaw Coin Hunter/1.0)",
|
||||
}
|
||||
if headers:
|
||||
merged_headers.update(headers)
|
||||
req = urllib.request.Request(url, headers=merged_headers)
|
||||
with urllib.request.urlopen(req, timeout=timeout) as resp:
|
||||
data = resp.read()
|
||||
return json.loads(data.decode("utf-8"))
|
||||
|
||||
|
||||
def print_json(data):
|
||||
print(json.dumps(data, ensure_ascii=False, indent=2))
|
||||
|
||||
|
||||
def bybit_ticker(symbol: str):
|
||||
url = (
|
||||
"https://api.bybit.com/v5/market/tickers?category=spot&symbol="
|
||||
+ urllib.parse.quote(symbol.upper())
|
||||
)
|
||||
payload = fetch_json(url)
|
||||
items = payload.get("result", {}).get("list", [])
|
||||
if not items:
|
||||
raise SystemExit(f"No Bybit spot ticker found for {symbol}")
|
||||
item = items[0]
|
||||
out = {
|
||||
"provider": "bybit",
|
||||
"symbol": symbol.upper(),
|
||||
"lastPrice": item.get("lastPrice"),
|
||||
"price24hPcnt": item.get("price24hPcnt"),
|
||||
"highPrice24h": item.get("highPrice24h"),
|
||||
"lowPrice24h": item.get("lowPrice24h"),
|
||||
"turnover24h": item.get("turnover24h"),
|
||||
"volume24h": item.get("volume24h"),
|
||||
"bid1Price": item.get("bid1Price"),
|
||||
"ask1Price": item.get("ask1Price"),
|
||||
}
|
||||
print_json(out)
|
||||
|
||||
|
||||
def bybit_klines(symbol: str, interval: str, limit: int):
|
||||
params = urllib.parse.urlencode({
|
||||
"category": "spot",
|
||||
"symbol": symbol.upper(),
|
||||
"interval": interval,
|
||||
"limit": str(limit),
|
||||
})
|
||||
url = f"https://api.bybit.com/v5/market/kline?{params}"
|
||||
payload = fetch_json(url)
|
||||
rows = payload.get("result", {}).get("list", [])
|
||||
out = {
|
||||
"provider": "bybit",
|
||||
"symbol": symbol.upper(),
|
||||
"interval": interval,
|
||||
"candles": [
|
||||
{
|
||||
"startTime": r[0],
|
||||
"open": r[1],
|
||||
"high": r[2],
|
||||
"low": r[3],
|
||||
"close": r[4],
|
||||
"volume": r[5],
|
||||
"turnover": r[6],
|
||||
}
|
||||
for r in rows
|
||||
],
|
||||
}
|
||||
print_json(out)
|
||||
|
||||
|
||||
def dexscreener_search(query: str):
|
||||
url = "https://api.dexscreener.com/latest/dex/search/?q=" + urllib.parse.quote(query)
|
||||
payload = fetch_json(url)
|
||||
pairs = payload.get("pairs") or []
|
||||
out = []
|
||||
for p in pairs[:10]:
|
||||
out.append({
|
||||
"chainId": p.get("chainId"),
|
||||
"dexId": p.get("dexId"),
|
||||
"pairAddress": p.get("pairAddress"),
|
||||
"url": p.get("url"),
|
||||
"baseToken": p.get("baseToken"),
|
||||
"quoteToken": p.get("quoteToken"),
|
||||
"priceUsd": p.get("priceUsd"),
|
||||
"liquidityUsd": (p.get("liquidity") or {}).get("usd"),
|
||||
"fdv": p.get("fdv"),
|
||||
"marketCap": p.get("marketCap"),
|
||||
"volume24h": (p.get("volume") or {}).get("h24"),
|
||||
"buys24h": ((p.get("txns") or {}).get("h24") or {}).get("buys"),
|
||||
"sells24h": ((p.get("txns") or {}).get("h24") or {}).get("sells"),
|
||||
})
|
||||
print_json({"provider": "dexscreener", "query": query, "pairs": out})
|
||||
|
||||
|
||||
def dexscreener_token(chain: str, address: str):
|
||||
url = f"https://api.dexscreener.com/tokens/v1/{urllib.parse.quote(chain)}/{urllib.parse.quote(address)}"
|
||||
payload = fetch_json(url)
|
||||
pairs = payload if isinstance(payload, list) else payload.get("pairs") or []
|
||||
out = []
|
||||
for p in pairs[:10]:
|
||||
out.append({
|
||||
"chainId": p.get("chainId"),
|
||||
"dexId": p.get("dexId"),
|
||||
"pairAddress": p.get("pairAddress"),
|
||||
"baseToken": p.get("baseToken"),
|
||||
"quoteToken": p.get("quoteToken"),
|
||||
"priceUsd": p.get("priceUsd"),
|
||||
"liquidityUsd": (p.get("liquidity") or {}).get("usd"),
|
||||
"fdv": p.get("fdv"),
|
||||
"marketCap": p.get("marketCap"),
|
||||
"volume24h": (p.get("volume") or {}).get("h24"),
|
||||
})
|
||||
print_json({"provider": "dexscreener", "chain": chain, "address": address, "pairs": out})
|
||||
|
||||
|
||||
def coingecko_search(query: str):
|
||||
url = "https://api.coingecko.com/api/v3/search?query=" + urllib.parse.quote(query)
|
||||
payload = fetch_json(url)
|
||||
coins = payload.get("coins") or []
|
||||
out = []
|
||||
for c in coins[:10]:
|
||||
out.append({
|
||||
"id": c.get("id"),
|
||||
"name": c.get("name"),
|
||||
"symbol": c.get("symbol"),
|
||||
"marketCapRank": c.get("market_cap_rank"),
|
||||
"thumb": c.get("thumb"),
|
||||
})
|
||||
print_json({"provider": "coingecko", "query": query, "coins": out})
|
||||
|
||||
|
||||
def coingecko_coin(coin_id: str):
|
||||
params = urllib.parse.urlencode({
|
||||
"localization": "false",
|
||||
"tickers": "false",
|
||||
"market_data": "true",
|
||||
"community_data": "false",
|
||||
"developer_data": "false",
|
||||
"sparkline": "false",
|
||||
})
|
||||
url = f"https://api.coingecko.com/api/v3/coins/{urllib.parse.quote(coin_id)}?{params}"
|
||||
payload = fetch_json(url)
|
||||
md = payload.get("market_data") or {}
|
||||
out = {
|
||||
"provider": "coingecko",
|
||||
"id": payload.get("id"),
|
||||
"symbol": payload.get("symbol"),
|
||||
"name": payload.get("name"),
|
||||
"marketCapRank": payload.get("market_cap_rank"),
|
||||
"currentPriceUsd": (md.get("current_price") or {}).get("usd"),
|
||||
"marketCapUsd": (md.get("market_cap") or {}).get("usd"),
|
||||
"fullyDilutedValuationUsd": (md.get("fully_diluted_valuation") or {}).get("usd"),
|
||||
"totalVolumeUsd": (md.get("total_volume") or {}).get("usd"),
|
||||
"priceChangePercentage24h": md.get("price_change_percentage_24h"),
|
||||
"priceChangePercentage7d": md.get("price_change_percentage_7d"),
|
||||
"priceChangePercentage30d": md.get("price_change_percentage_30d"),
|
||||
"circulatingSupply": md.get("circulating_supply"),
|
||||
"totalSupply": md.get("total_supply"),
|
||||
"maxSupply": md.get("max_supply"),
|
||||
"homepage": (payload.get("links") or {}).get("homepage", [None])[0],
|
||||
}
|
||||
print_json(out)
|
||||
|
||||
|
||||
def birdeye_token(address: str):
|
||||
api_key = os.getenv("BIRDEYE_API_KEY") or os.getenv("BIRDEYE_APIKEY")
|
||||
if not api_key:
|
||||
raise SystemExit("Birdeye requires BIRDEYE_API_KEY in the environment")
|
||||
url = "https://public-api.birdeye.so/defi/token_overview?address=" + urllib.parse.quote(address)
|
||||
payload = fetch_json(url, headers={
|
||||
"x-api-key": api_key,
|
||||
"x-chain": "solana",
|
||||
})
|
||||
print_json({"provider": "birdeye", "address": address, "data": payload.get("data")})
|
||||
|
||||
|
||||
def build_parser():
|
||||
parser = argparse.ArgumentParser(description="Coin Hunter market data probe")
|
||||
sub = parser.add_subparsers(dest="command", required=True)
|
||||
|
||||
p = sub.add_parser("bybit-ticker", help="Fetch Bybit spot ticker")
|
||||
p.add_argument("symbol")
|
||||
|
||||
p = sub.add_parser("bybit-klines", help="Fetch Bybit spot klines")
|
||||
p.add_argument("symbol")
|
||||
p.add_argument("--interval", default="60", help="Bybit interval, e.g. 1, 5, 15, 60, 240, D")
|
||||
p.add_argument("--limit", type=int, default=10)
|
||||
|
||||
p = sub.add_parser("dex-search", help="Search DexScreener by query")
|
||||
p.add_argument("query")
|
||||
|
||||
p = sub.add_parser("dex-token", help="Fetch DexScreener token pairs by chain/address")
|
||||
p.add_argument("chain")
|
||||
p.add_argument("address")
|
||||
|
||||
p = sub.add_parser("gecko-search", help="Search CoinGecko")
|
||||
p.add_argument("query")
|
||||
|
||||
p = sub.add_parser("gecko-coin", help="Fetch CoinGecko coin by id")
|
||||
p.add_argument("coin_id")
|
||||
|
||||
p = sub.add_parser("birdeye-token", help="Fetch Birdeye token overview (Solana)")
|
||||
p.add_argument("address")
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def main():
|
||||
parser = build_parser()
|
||||
args = parser.parse_args()
|
||||
if args.command == "bybit-ticker":
|
||||
bybit_ticker(args.symbol)
|
||||
elif args.command == "bybit-klines":
|
||||
bybit_klines(args.symbol, args.interval, args.limit)
|
||||
elif args.command == "dex-search":
|
||||
dexscreener_search(args.query)
|
||||
elif args.command == "dex-token":
|
||||
dexscreener_token(args.chain, args.address)
|
||||
elif args.command == "gecko-search":
|
||||
coingecko_search(args.query)
|
||||
elif args.command == "gecko-coin":
|
||||
coingecko_coin(args.coin_id)
|
||||
elif args.command == "birdeye-token":
|
||||
birdeye_token(args.address)
|
||||
else:
|
||||
parser.error("Unknown command")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user