SKILL.md - Add triggers/mode to frontmatter for better skill routing - Add mandatory JSON decision skeleton before every trade - Add multi-source confirmation rule and common-mistakes guardrails - Add prediction logging to hourly review workflow - Restructure References into an explicit routing table CLAUDE.md - Add Reference routing table for agent context - Fix remaining Hermes-only wording in gate description references/user-data-layout.md - Add complete log schema: decisions, trades, predictions, errors - Document predictions_YYYYMMDD.jsonl for calibration feedback loop README.md - Mention prediction tracking in "Why it works" - Update runtime directory layout to include predictions.jsonl references/shim-templates.md - Show platform cron config usage examples
20 KiB
name, description, triggers, mode
| name | description | triggers | mode | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Coin Hunter | Hybrid short-term crypto trading system — combining mainstream coin scalping with meme-coin opportunistic rotation, backed by hourly review, prediction tracking, and continuous strategy iteration. |
|
agent-assisted |
Coin Hunter
Overview
Coin Hunter is a short-term trading framework, not just a meme-coin scanner.
It operates on two tracks:
- Mainstream Short-Term (70%) — Trade liquid, high-volume coins (BTC, ETH, SOL, DOGE, PEPE, etc.) based on technical momentum, support/resistance, and market structure.
- Meme / 妖币 Rotation (30%) — Opportunistically rotate into breakout meme coins when narrative heat, volume, and timing align.
Core principle:
- Profit maximization through concentration + discipline.
- 妖币可遇不可求 — when a runner appears, capture it. When none exists, do not force trades; instead, scalp mainstream coins or sit in USDT.
- Every decision is logged, and every hour is reviewed for quality and parameter tuning.
Portfolio-first rule
Always check the user's actual portfolio state under ~/.coinhunter/ before giving trade advice or executing orders.
Files to inspect:
positions.jsonaccounts.jsonlogs/decisions_YYYYMMDD.jsonllogs/trades_YYYYMMDD.jsonlreviews/review_YYYYMMDD_HHMMSS.json
Anchor all advice to the user's real balances, average costs, exchange, and current exposure.
Supported modes
- Single-coin triage — analyze a specific holding (mainstream or meme).
- Active discovery — scan for the best short-term opportunity across both mainstream and meme sectors.
- Execution — run trades via the CLI (
coinhunter exec), evaluating whether to hold, sell, or rebalance. - Review — generate an hourly report on decision quality, PnL, and recommended parameter adjustments.
Scientific analysis checklist (mandatory before every trade decision)
Before executing or recommending any action, answer:
- Trend posture — Is price above/below short-term MAs (1h/4h)?
- Volume-price fit — Is volume expanding with the move or diverging?
- Key levels — Where is the next support/resistance? How much room to run?
- Market context — Is BTC/ETH supportive or contradictory?
- Opportunity cost — Is holding current coin better than switching to new coin or sitting in USDT?
- Time window — Is this a good entry/exit time (liquidity, session, news flow)?
Read references/short-term-trading-framework.md before every active decision pass.
Decision calibration (mandatory JSON skeleton)
Before finalizing any HOLD / SELL_ALL / REBALANCE / BUY decision, output this JSON block. It forces alignment between reasoning and action.
{
"decision": "HOLD",
"confidence": 0.75,
"primary_reason": "BTC regime bearish contradicts long bias",
"risk_reward": 0.8,
"time_horizon_hours": 4,
"stop_loss": 0.0,
"take_profit": 0.0,
"max_loss_pct": 0.07
}
Rules:
confidencemust be 0.0–1.0. If < 0.55, default to HOLD unless there is an urgent risk-off reason.risk_rewardmust be ≥ 1.0 to justify a new entry.stop_lossandtake_profitmust be explicit numbers (not "TBD").- Only after outputting this JSON may you proceed to
coinhunter exec.
Multi-source confirmation rule
A signal strengthens only when confirmed by 2 or more independent data sources:
- Price action + volume expansion on Bybit/Binance
- Narrative heat on Twitter/X + DEX flow on DexScreener
- CEX listing rumor from exchange announcement + on-chain holder growth
If a signal comes from a single source only, downgrade confidence by 0.15–0.25.
Common mistakes to avoid
- Do NOT estimate PnL from memory; always read
positions.jsonfirst. - Do NOT chase a coin that only appears on a single tiny DEX with no social footprint.
- Do NOT output a trade recommendation without stating the exact stop-loss level.
- Do NOT ignore contradictory BTC/ETH regime shifts when evaluating altcoin setups.
- Do NOT override the position-sizing table based on "gut feeling."
Workflow
Discovery & Scanning
- Mainstream scan — Use
coinhunter probe bybit-tickeror ccxt for liquid coins.- Look for: breakouts, volume spikes, S/R flips, trend alignment.
- Meme scan — Use
web_search+dex-search/gecko-searchfor narrative heat.- Look for: accelerating attention, DEX flow, CEX listing rumors, social spread.
- Cross-compare — Score the top 3-5 candidates against current holdings.
Execution
- Read balances and positions.
- Pull market data for holdings and candidates.
- Run the 6-question scientific checklist.
- Output the decision calibration JSON skeleton.
- Decide: HOLD / SELL_ALL / REBALANCE / BUY.
- Execute via the CLI (
coinhunter exec ...). - Write a
predictionentry to~/.coinhunter/logs/predictions_YYYYMMDD.jsonlwith expected price range and validation timestamp.
Review (every hour)
- Run
coinhunter recapto analyze all decisions from the past hour. - Compare decision prices to current prices.
- Read
~/.coinhunter/logs/predictions_YYYYMMDD.jsonland score prediction accuracy:- If price landed inside the predicted range → +1 calibrated point
- If price moved opposite to the predicted direction → flag systematic bias
- If stop-loss was hit faster than predicted → widen risk buffer or reduce position size
- Flag patterns: missed runs, bad entries, over-trading, hesitation.
- Output recommendations for parameter or blacklist adjustments.
- Save the review report to
~/.coinhunter/reviews/.
Auto-trading architecture
Install the executable CLI first:
pipx install coinhunter
# or: pip install coinhunter
| CLI Command | Purpose |
|---|---|
coinhunter exec |
Order execution layer (buy / flat / rotate / hold) |
coinhunter pre |
Lightweight threshold evaluator and trigger gate |
coinhunter review |
Generate compact review context for the agent |
coinhunter recap |
Hourly quality review and optimization suggestions |
coinhunter probe |
Market data fetcher |
Execution schedule
- Trade bot — runs every 15-30 minutes via
cronjob. - Review bot — runs every 1-12 hours via
cronjob, depending on how much manual oversight is needed.
Low-cost cron architecture
When model cost or quota is tight, do not let every cron run perform full analysis from scratch.
Recommended pattern:
- Attach a lightweight Python
scriptto the cron job (under your platform's scripts directory, e.g.~/.hermes/scripts/or~/.openclaw/scripts/) that fetches balances/tickers, computes hashes, and emits compact JSON context. - Cache the last observed positions, top candidates, market regime, and
last_deep_analysis_atunder~/.coinhunter/state/. - Trigger full analysis only when one of these changes materially. Make the thresholds adaptive instead of fixed:
- position structure changes (hard trigger)
- per-position price/PnL moves beyond thresholds that widen for micro-capital / dust accounts and narrow during higher-volatility sessions
- top candidate leadership changes materially, but discount this signal when free USDT is below actionable exchange minimums
- BTC/ETH regime changes (hard trigger)
- a max staleness timer forces refresh, with longer refresh windows for micro accounts to avoid pointless re-analysis
- In the cron prompt, if the injected context says
should_analyze=false, respond with exactly[SILENT]and do not call tools. - After a triggered deep-analysis pass completes, acknowledge it from the agent (for example by running the precheck script with an
--ackflag) so the trigger is cleared. - For even lower spend, move the high-frequency cadence outside Hermes cron entirely:
- install a system
crontabentry that runs a local gate script every 5-10 minutes - let that gate script run the lightweight precheck
- only when
should_analyze=trueand no run is already queued, trigger your platform's cron job (e.g.hermes cron run <job_id>oropenclaw trigger <job_id>) - store a
run_requested_atmarker in~/.coinhunter/state/precheck_state.jsonand clear it when the analysis acknowledges completion
- install a system
This pattern preserves auto-delivery from your platform's cron system while reducing model wakeups to trigger-only events.
Practical production notes for external gate mode
- Put the external gate itself on system
crontab(for example every 5 minutes) rather than on Hermes cron. That keeps the high-frequency loop completely local and model-free. - Keep the Hermes trading cron job on a low-frequency fallback schedule (for example once daily at 05:00 local time) so the main execution path remains trigger-driven.
- Add a file lock around the external gate script so overlapping system-cron invocations cannot double-trigger.
- Rotate
~/.coinhunter/logs/external_gate.logwithlogrotate(daily, keep ~14 compressed copies,copytruncate) and schedule the rotation a few minutes after the fallback Hermes cron run so they do not overlap.
Building your own gate (step-by-step)
If you want to replicate this low-cost trigger architecture, here is a complete blueprint.
1. File layout
User runtime state lives under ~/.coinhunter/state/:
~/.coinhunter/state/
precheck_state.json # last snapshot + trigger flags
external_gate.lock # flock file for external gate
2. State schema (precheck_state.json)
{
"last_positions_hash": "sha256_of_positions_json",
"last_top_candidates_hash": "sha256_of_top_5_coins",
"last_btc_regime": "bullish|neutral|bearish",
"last_deep_analysis_at": "2026-04-15T11:00:00Z",
"free_usdt": 12.50,
"account_total_usdt": 150.00,
"run_requested_at": null,
"run_acknowledged_at": "2026-04-15T11:05:00Z",
"volatility_session": "low|medium|high",
"staleness_hours": 2.0
}
3. Precheck script logic (pseudocode)
import json, hashlib, os, math
from datetime import datetime, timezone
STATE_PATH = os.path.expanduser("~/.coinhunter/state/precheck_state.json")
POSITIONS_PATH = os.path.expanduser("~/.coinhunter/positions.json")
def load_json(path):
with open(path) as f:
return json.load(f)
def save_json(path, obj):
tmp = path + ".tmp"
with open(tmp, "w") as f:
json.dump(obj, f, indent=2)
os.replace(tmp, path)
def compute_hash(obj):
return hashlib.sha256(json.dumps(obj, sort_keys=True).encode()).hexdigest()[:16]
def adaptive_thresholds(account_total_usdt, volatility_session):
# Micro accounts get wider thresholds; high volatility narrows them
base_price = 0.03 if account_total_usdt >= 100 else 0.08
base_pnl = 0.05 if account_total_usdt >= 100 else 0.12
vol_mult = {"low": 1.2, "medium": 1.0, "high": 0.7}.get(volatility_session, 1.0)
return base_price * vol_mult, base_pnl * vol_mult
def should_analyze():
state = load_json(STATE_PATH) if os.path.exists(STATE_PATH) else {}
positions = load_json(POSITIONS_PATH)
# ... fetch current tickers, BTC regime, free USDT here ...
new_pos_hash = compute_hash(positions.get("positions", []))
new_btc_regime = "neutral" # replace with actual analysis
new_free = positions.get("balances", {}).get("USDT", {}).get("free", 0)
total = positions.get("account_total_usdt", 0)
volatility = "medium" # replace with actual session metric
price_thr, pnl_thr = adaptive_thresholds(total, volatility)
triggers = []
if new_pos_hash != state.get("last_positions_hash"):
triggers.append("position_change")
if new_btc_regime != state.get("last_btc_regime"):
triggers.append("btc_regime_change")
# ... check per-position price/PnL drift vs thresholds ...
# ... check candidate leadership change (skip if free_usdt < min_actionable) ...
staleness = (datetime.now(timezone.utc) - datetime.fromisoformat(state.get("last_deep_analysis_at","2000-01-01T00:00:00+00:00"))).total_seconds() / 3600.0
max_staleness = 4.0 if total >= 100 else 8.0
if staleness >= max_staleness:
triggers.append("staleness")
decision = bool(triggers)
state.update({
"last_positions_hash": new_pos_hash,
"last_btc_regime": new_btc_regime,
"free_usdt": new_free,
"account_total_usdt": total,
"volatility_session": volatility,
"staleness_hours": staleness,
})
if decision:
state["run_requested_at"] = datetime.now(timezone.utc).isoformat()
save_json(STATE_PATH, state)
return {"should_analyze": decision, "triggers": triggers, "state": state}
if __name__ == "__main__":
result = should_analyze()
print(json.dumps(result))
4. Cron job configuration
Attach the precheck script as the script field of the cron job so its JSON output is injected into the prompt.
Hermes example:
{
"id": "coinhunter-trade",
"schedule": "*/15 * * * *",
"prompt": "You are Coin Hunter. If the injected context says should_analyze=false, respond with exactly [SILENT] and do nothing. Otherwise, read ~/.coinhunter/positions.json, run the scientific checklist, decide HOLD/SELL/REBALANCE/BUY, and execute via the `coinhunter` CLI. After finishing, run `coinhunter pre --ack` to clear the trigger.",
"script": "coinhunter_shim.py pre",
"deliver": "telegram",
"model": "kimi-for-coding"
}
OpenClaw example:
{
"id": "coinhunter-trade",
"schedule": "*/15 * * * *",
"prompt": "You are Coin Hunter. If the injected context says should_analyze=false, respond with exactly [SILENT] and do nothing. Otherwise, read ~/.coinhunter/positions.json, run the scientific checklist, decide HOLD/SELL/REBALANCE/BUY, and execute via the `coinhunter` CLI. After finishing, run `coinhunter pre --ack` to clear the trigger.",
"script": "coinhunter_shim.py pre",
"deliver": "webhook"
}
Acknowledge completion by running coinhunter pre --ack so the gate clears run_requested_at and does not re-fire until the next true trigger.
5. External gate (optional, for even lower cost)
If you want to run the precheck every 5 minutes without waking Hermes at all:
External gate pseudocode (run from your platform's scripts directory):
import fcntl, os, subprocess, json, sys
LOCK_PATH = os.path.expanduser("~/.coinhunter/state/external_gate.lock")
JOB_ID = "coinhunter-trade"
PLATFORM_PATH = os.path.expanduser("~/.coinhunter/platform.json")
# Load platform config if it exists; default to Hermes behavior
platform = {"cron_command": ["hermes", "cron", "run"]}
if os.path.exists(PLATFORM_PATH):
platform.update(json.load(open(PLATFORM_PATH)))
cron_command = platform.get("cron_command", ["hermes", "cron", "run"])
with open(LOCK_PATH, "w") as f:
try:
fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
except BlockingIOError:
sys.exit(0) # another instance is running
result = json.loads(os.popen("coinhunter pre").read())
if result.get("should_analyze"):
# Trigger platform cron only if not already requested
state_path = os.path.expanduser("~/.coinhunter/state/precheck_state.json")
state = json.load(open(state_path))
if not state.get("run_requested_at"):
subprocess.run([*cron_command, JOB_ID], check=False)
System crontab entry:
*/5 * * * * /usr/bin/env coinhunter gate >> /home/user/.coinhunter/logs/external_gate.log 2>&1
With this setup, the model is only invoked when a material market change occurs—preserving intelligence while cutting routine cost by 80-95%.
Troubleshooting common precheck errors
When coinhunter pre fails with status: deep_analysis_required and reasons: ["precheck-error"], inspect the details field and apply these known fixes:
-
'PosixPath' object has no attribute 'env_file'- Location: inside the installed
coinhunterpackage (src/coinhunter/services/market_data.pyin the PyPI source) - Cause:
load_env_file(ENV_FILE)is passed aPathobject, butload_env_file()expects either aRuntimePathsdataclass or no arguments. - Fix: Update
coinhunterto the latest version from PyPI. If the bug persists, patch the installed package and submit an issue to thecoinhunterproject.
- Location: inside the installed
-
name 'BASE_PN_L_TRIGGER_PCT' is not defined- Location: inside the installed
coinhunterpackage (src/coinhunter/services/adaptive_profile.pyin the PyPI source) - Cause: Typo
BASE_PN_L_TRIGGER_PCTinstead ofBASE_PNL_TRIGGER_PCT. - Fix: Update
coinhunterto the latest version from PyPI. If the bug persists, patch the installed package and submit an issue to thecoinhunterproject.
- Location: inside the installed
After updating, rerun coinhunter pre to verify the gate clears before executing the trading decision.
Production hardening (mandatory)
The live trading stack must include these safeguards:
- Idempotency — every decision carries a
decision_id. The executor checks~/.coinhunter/executions.jsonbefore submitting orders to prevent duplicate trades. - Exchange reconciliation — before every run, pull real Binance balances and recent trades to sync
positions.json. Do not trust local state alone. - File locking + atomic writes —
positions.jsonandexecutions.jsonare updated under a file lock and written to a temp file before atomic rename. - Order precision validation — read Binance
lotSize,stepSize, andminNotionalfilters via ccxt before any order. Round quantities correctly and reject orders below minimums. - Fee buffer — keep ~2%-5% USDT unallocated so that slippage and fees do not cause "insufficient balance" rejections.
- Structured logging — every decision, trade, error, and balance snapshot is written as JSONL under
~/.coinhunter/logs/withschema_versionanddecision_id. - Error logging — failed API calls, rejected orders, and reconciliation mismatches are captured in
logs/errors_YYYYMMDD.jsonland fed into the hourly review.
Cross-platform deployment
Coin Hunter is runtime-agnostic. It works on Hermes, OpenClaw, and any compatible cron-based platform.
-
Install the CLI (same everywhere):
pipx install coinhunter -
Place the shim in your platform's scripts directory:
- Hermes:
~/.hermes/scripts/coinhunter_shim.py - OpenClaw:
~/.openclaw/scripts/coinhunter_shim.py
- Hermes:
-
(Optional) Create
~/.coinhunter/platform.jsonif you want the external gate to use a non-default trigger command. When absent, the gate falls back to Hermes behavior (hermes cron run).
Safety rules
- No leverage/futures when capital < $200.
- When capital < $50, concentrate into 1 position only.
- Always leave 2%-5% USDT buffer for fees and slippage.
- Blacklist updates should be driven by review findings.
Position sizing
| Total Capital | Strategy |
|---|---|
| < $50 | Single-coin concentration (mainstream or meme) |
| $50 – $200 | 60% mainstream + 40% meme, max 2 positions |
| > $200 | Up to 3 positions with stricter risk per position |
Output style
For live decisions
Concise Telegram-style report:
- Current holdings + live PnL
- Top 1-2 opportunities found
- Decision and exact reasoning
- Action confirmation (or [DRY RUN] note)
For hourly reviews
Use references/review-template.md structure:
- Decision quality breakdown
- Market context
- Strategy adjustments recommended
- Action items for next hour
Reference routing
Read these files at the exact moments below. Do not skip them.
| When | Read this |
|---|---|
| Before every active trade decision (mainstream) | references/short-term-trading-framework.md |
| Before every active trade decision (meme) | references/short-term-trading-framework.md + references/scam-signals.md |
| Data source conflict or ambiguity | references/provider-playbook.md |
| Hourly review | references/review-template.md |
| Setting up runtime state or logging schema | references/user-data-layout.md |
| Deploying auto-trading or Binance API | references/auto-trading-guide.md |
| Evaluating output format | references/output-templates.md |
| Running proactive discovery scans | references/search-workflow.md |