refactor: decouple Coin Hunter from Hermes for cross-platform usage

- Add unified coinhunter_shim.py that accepts subcommands (pre/gate/review/rotate-log)
- Update SKILL.md gate pseudocode to read optional ~/.coinhunter/platform.json
- Split cron/setup examples into Hermes and OpenClaw variants across docs
- Introduce platform.json schema in user-data-layout.md
- Remove stale auto_trader.py/run_trader.sh references from auto-trading-guide.md
- Keep legacy shims as backward-compatible wrappers
This commit is contained in:
2026-04-16 03:03:25 +08:00
parent 863d10b872
commit c07b9c1ae5
12 changed files with 409 additions and 110 deletions

114
CLAUDE.md Normal file
View File

@@ -0,0 +1,114 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Repository purpose
This is a **cross-platform skill package** for a short-term crypto trading framework called Coin Hunter. It runs on Hermes, OpenClaw, and compatible cron-based runtimes. It contains the skill specification, reference playbooks, and runtime shim templates.
The actual trading CLI is an **external dependency**: the `coinhunter` package on PyPI. All execution flows through the installed `coinhunter` command. This repository does **not** contain the CLI source code or a build system.
## Repository structure
- `SKILL.md` — The canonical behavior specification. This is the source of truth for the trading framework, including the scientific checklist, execution workflow, review workflow, auto-trading architecture, low-cost gate design, production hardening rules, and troubleshooting notes.
- `README.md` — User-facing quick-start and overview.
- `references/` — Trading playbooks and templates:
- `short-term-trading-framework.md` — Hybrid strategy (70% mainstream scalping / 30% meme rotation) and position-sizing rules.
- `provider-playbook.md` — Data source hierarchy (Bybit → DexScreener → Birdeye → CoinGecko) and token identity hygiene.
- `user-data-layout.md` — Schema for private runtime state under `~/.coinhunter/`.
- `review-template.md` — Hourly review report structure.
- `scam-signals.md` — Red flags and classification guidance for meme-coin evaluation.
- `auto-trading-guide.md` — Legacy-oriented guide for deploying `auto_trader.py` and Binance API setup.
- `templates/` — Thin shim scripts meant to be copied to your platform's scripts directory (e.g. `~/.hermes/scripts/` or `~/.openclaw/scripts/`). Each shim invokes the installed `coinhunter` CLI:
- `coinhunter_precheck_shim.py` — Runs `coinhunter pre`.
- `coinhunter_external_gate_shim.py` — Runs `coinhunter gate`.
- `coinhunter_review_context_shim.py` — Runs `coinhunter review`.
- `rotate_external_gate_log_shim.py` — Runs `coinhunter rotate-log`.
There is no `pyproject.toml`, `Makefile`, or test suite in this repository.
## Key architectural concepts
### Skill vs runtime separation
- **Skill code/docs** live in this repository.
- **Private user state** lives under `~/.coinhunter/` (positions, balances, logs, reviews, cache, gate state). Never commit user data into this repo.
- **Platform cron scripts** are copied from `templates/` to your runtime's scripts directory (e.g. `~/.hermes/scripts/` or `~/.openclaw/scripts/`) and invoke the installed `coinhunter` CLI.
### Low-cost trigger architecture
The framework is designed to minimize LLM invocations:
1. A lightweight local Python precheck script decides whether market conditions have changed materially.
2. If `should_analyze=false`, the cron job emits `[SILENT]` and exits.
3. If `should_analyze=true`, the LLM performs deep analysis and may execute trades.
4. An optional external gate (system crontab) can run the precheck every 5 minutes and trigger the Hermes cron only on true events.
See `SKILL.md` (sections "Low-cost cron architecture" and "Building your own gate") for the full pseudocode, file layout, state schema, and troubleshooting.
### Trading workflow
1. **Portfolio-first rule** — Always read `~/.coinhunter/positions.json`, `accounts.json`, and recent logs before giving trade advice.
2. **Scientific checklist** (mandatory before every decision) — trend posture, volume-price fit, key levels, BTC/ETH context, opportunity cost, time window.
3. **Execution** — Decide HOLD / SELL_ALL / REBALANCE / BUY. Use `coinhunter exec` for order execution.
4. **Review** — Run `coinhunter recap` hourly to analyze decision quality and tune parameters.
### Production hardening requirements
When modifying or adding trading scripts, these safeguards from `SKILL.md` must be respected:
- **Idempotency** — every decision carries a `decision_id`; check `~/.coinhunter/executions.json` before submitting orders.
- **Exchange reconciliation** — pull real balances before every run; do not trust local state alone.
- **Atomic writes** — update `positions.json` and `executions.json` under a file lock with temp-file + rename.
- **Order precision validation** — read exchange `lotSize`, `stepSize`, and `minNotional` filters via ccxt before any order.
- **Fee buffer** — keep 2%5% USDT unallocated.
- **Structured logging** — write JSONL under `~/.coinhunter/logs/` with `schema_version` and `decision_id`.
- **Platform config atomic writes** — if you create or modify `~/.coinhunter/platform.json`, write to a temp file and rename it into place, just like `positions.json` and `executions.json`.
### Safety rules
- No leverage/futures when capital < $200.
- When capital < $50, concentrate into **1 position only**.
- Blacklist updates should be driven by review findings.
## Common commands
- **Install the CLI tool:**
```bash
pipx install coinhunter
# verify
coinhunter --version
```
- **Validate a shim after editing:**
```bash
python3 -m py_compile templates/coinhunter_precheck_shim.py
```
- **Copy shims to your platform's scripts directory:**
```bash
# Unified shim (recommended)
cp templates/coinhunter_shim.py ~/.hermes/scripts/coinhunter_shim.py
# or: cp templates/coinhunter_shim.py ~/.openclaw/scripts/coinhunter_shim.py
# Legacy individual shims (Hermes backward compatibility)
cp templates/coinhunter_precheck_shim.py ~/.hermes/scripts/coinhunter_precheck.py
cp templates/coinhunter_external_gate_shim.py ~/.hermes/scripts/coinhunter_external_gate.py
cp templates/coinhunter_review_context_shim.py ~/.hermes/scripts/coinhunter_review_context.py
```
- **Inspect user state:**
```bash
cat ~/.coinhunter/positions.json
cat ~/.coinhunter/accounts.json
ls ~/.coinhunter/logs/
ls ~/.coinhunter/reviews/
```
- **Common trading CLI commands:**
```bash
coinhunter pre
coinhunter exec
coinhunter recap
coinhunter review
coinhunter probe bybit-ticker
```
## When making changes
- If you change `SKILL.md`, check whether `README.md` needs corresponding updates.
- If you change shim templates, validate them with `python3 -m py_compile` before copying to your platform's scripts directory.
- Keep the separation between this repo and `~/.coinhunter/` — never write personal account data or logs into the skill directory.

106
README.md
View File

@@ -37,29 +37,30 @@
```mermaid ```mermaid
flowchart TD flowchart TD
A[System crontab<br/>every 5 min] -->|local python| B[External Gate] A[System crontab<br/>every 5 min] -->|coinhunter gate| B[External Gate]
B --> C{should_analyze?} B --> C{should_analyze?}
C -->|No| D[Silent exit<br/>zero cost] C -->|No| D[Silent exit<br/>zero cost]
C -->|Yes| E[Trigger Hermes cron] C -->|Yes| E[Trigger platform cron]
E --> F[LLM Deep Analysis] E --> F[LLM Deep Analysis]
F --> G[smart_executor.py] F --> G[coinhunter exec]
G --> H[Binance API] G --> H[Binance API]
F --> I[logger.py] F --> I[coinhunter logs]
I --> J[~/.coinhunter/logs/] I --> J[~/.coinhunter/logs/]
K[review_engine.py<br/>hourly] --> J K[coinhunter recap<br/>hourly] --> J
``` ```
### Key components ### Key components
| File | Purpose | All operations go through the installed `coinhunter` CLI. This skill provides the framework specification, reference playbooks, and Hermes cron shims.
|------|---------|
| `scripts/market_probe.py` | Market data fetcher (ccxt + web search) | | Command | Purpose |
| `scripts/coinhunter_precheck.py` | **Lightweight gate** — computes adaptive thresholds and decides if analysis is needed | |---------|---------|
| `scripts/coinhunter_external_gate.py` | Optional **system-crontab wrapper** that runs the gate entirely outside Hermes | | `coinhunter probe` | Market data fetcher (ccxt + web search) |
| `scripts/coinhunter_cli.py` | Unified CLI entrypoint for CoinHunter operations | | `coinhunter pre` | **Lightweight gate** — computes adaptive thresholds and decides if analysis is needed |
| `scripts/smart_executor.py` | Order execution layer with idempotency & precision validation | | `coinhunter gate` | Optional **system-crontab wrapper** that runs the gate entirely outside Hermes |
| `scripts/logger.py` | Structured JSONL logging of every decision & trade | | `coinhunter exec` | Order execution layer with idempotency & precision validation |
| `scripts/review_engine.py` | Hourly quality review & parameter optimization | | `coinhunter review` | Generate compact review context for the agent |
| `coinhunter recap` | Hourly quality review & parameter optimization |
--- ---
@@ -72,10 +73,21 @@ git clone https://github.com/TacitLab/coinhunter.git
cd coinhunter cd coinhunter
``` ```
### 2. Set up your runtime directory ### 2. Install the CLI tool
```bash ```bash
mkdir -p ~/.coinhunter/state ~/.coinhunter/logs ~/.hermes/scripts pipx install coinhunter
# verify
coinhunter --help
```
### 3. Set up your runtime directory
```bash
mkdir -p ~/.coinhunter/state ~/.coinhunter/logs
# Also create your platform's scripts directory if needed:
# mkdir -p ~/.hermes/scripts
# mkdir -p ~/.openclaw/scripts
``` ```
Create your initial `positions.json`: Create your initial `positions.json`:
@@ -89,30 +101,64 @@ Create your initial `positions.json`:
} }
``` ```
### 3. Build the gate ### 4. Deploy the shims
Copy the precheck blueprint from [`SKILL.md`](./SKILL.md) into `~/.hermes/scripts/coinhunter_precheck.py`. **Option A — unified shim (recommended for new setups and cross-platform):**
It is ~100 lines of pure Python: reads your state, hashes positions, checks adaptive price/PnL thresholds, and outputs a tiny JSON decision.
### 4. Configure the Hermes cron job Copy the single unified shim into your platform's scripts directory. It accepts the subcommand as its first argument:
```bash
# Hermes
cp templates/coinhunter_shim.py ~/.hermes/scripts/coinhunter_shim.py
# OpenClaw
cp templates/coinhunter_shim.py ~/.openclaw/scripts/coinhunter_shim.py
```
**Option B — legacy shims (existing Hermes users, unchanged behavior):**
The original individual shims are still provided for backward compatibility:
```bash
cp templates/coinhunter_precheck_shim.py ~/.hermes/scripts/coinhunter_precheck.py
cp templates/coinhunter_external_gate_shim.py ~/.hermes/scripts/coinhunter_external_gate.py
cp templates/coinhunter_review_context_shim.py ~/.hermes/scripts/coinhunter_review_context.py
cp templates/rotate_external_gate_log_shim.py ~/.hermes/scripts/rotate_external_gate_log.py
```
### 5. Configure the platform cron job
**Hermes example (using the unified shim):**
```json ```json
{ {
"id": "coinhunter-trade", "id": "coinhunter-trade",
"schedule": "*/15 * * * *", "schedule": "*/15 * * * *",
"prompt": "You are Coin Hunter. If injected context says should_analyze=false, respond with exactly [SILENT]. Otherwise read positions.json, run the scientific checklist, decide HOLD/SELL/REBALANCE/BUY, and execute.", "prompt": "You are Coin Hunter. If injected context says should_analyze=false, respond with exactly [SILENT]. Otherwise read positions.json, run the scientific checklist, decide HOLD/SELL/REBALANCE/BUY, and execute.",
"script": "~/.hermes/scripts/coinhunter_precheck.py", "script": "coinhunter_shim.py pre",
"deliver": "telegram", "deliver": "telegram",
"model": "kimi-for-coding" "model": "kimi-for-coding"
} }
``` ```
### 5. (Optional) Add the external gate **OpenClaw example:**
Put this in your system crontab to run the precheck every **5 minutes** without ever waking the LLM: ```json
{
"id": "coinhunter-trade",
"schedule": "*/15 * * * *",
"prompt": "You are Coin Hunter. If injected context says should_analyze=false, respond with exactly [SILENT]. Otherwise read positions.json, run the scientific checklist, decide HOLD/SELL/REBALANCE/BUY, and execute.",
"script": "coinhunter_shim.py pre",
"deliver": "webhook"
}
```
### 6. (Optional) Add the external gate
Put this in your system crontab to run the gate every **5 minutes** without ever waking the LLM:
```cron ```cron
*/5 * * * * /usr/bin/python3 /home/user/.hermes/scripts/coinhunter_external_gate.py >> /home/user/.coinhunter/logs/external_gate.log 2>&1 */5 * * * * /usr/bin/env coinhunter gate >> /home/user/.coinhunter/logs/external_gate.log 2>&1
``` ```
--- ---
@@ -160,11 +206,13 @@ See the full step-by-step gate blueprint in [`SKILL.md`](./SKILL.md).
coinhunter/ coinhunter/
├── README.md # You are here ├── README.md # You are here
├── SKILL.md # Full framework spec + gate blueprint ├── SKILL.md # Full framework spec + gate blueprint
├── scripts/ ├── CLAUDE.md # Guidance for Claude Code
│ ├── market_probe.py # Market data fetcher ├── templates/ # Platform cron shims (call the installed coinhunter CLI)
│ ├── init_user_state.py # Bootstrap helper │ ├── coinhunter_shim.py # Unified cross-platform shim (recommended)
│ ├── auto_trader.py # Reference trading loop │ ├── coinhunter_precheck_shim.py
── ... # Your gate scripts live in ~/.hermes/scripts/ ── coinhunter_external_gate_shim.py
│ ├── coinhunter_review_context_shim.py
│ └── rotate_external_gate_log_shim.py
└── references/ └── references/
├── short-term-trading-framework.md ├── short-term-trading-framework.md
├── review-template.md ├── review-template.md

View File

@@ -76,6 +76,12 @@ Read `references/short-term-trading-framework.md` before every active decision p
## Auto-trading architecture ## Auto-trading architecture
Install the executable CLI first:
```bash
pipx install coinhunter
# or: pip install coinhunter
```
| CLI Command | Purpose | | CLI Command | Purpose |
|-------------|---------| |-------------|---------|
| `coinhunter exec` | Order execution layer (buy / flat / rotate / hold) | | `coinhunter exec` | Order execution layer (buy / flat / rotate / hold) |
@@ -92,7 +98,7 @@ Read `references/short-term-trading-framework.md` before every active decision p
When model cost or quota is tight, do not let every cron run perform full analysis from scratch. When model cost or quota is tight, do not let every cron run perform full analysis from scratch.
Recommended pattern: Recommended pattern:
1. Attach a lightweight Python `script` to the cron job (under `~/.hermes/scripts/`) that fetches balances/tickers, computes hashes, and emits compact JSON context. 1. Attach a lightweight Python `script` to 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.
2. Cache the last observed positions, top candidates, market regime, and `last_deep_analysis_at` under `~/.coinhunter/state/`. 2. Cache the last observed positions, top candidates, market regime, and `last_deep_analysis_at` under `~/.coinhunter/state/`.
3. Trigger full analysis only when one of these changes materially. Make the thresholds adaptive instead of fixed: 3. Trigger full analysis only when one of these changes materially. Make the thresholds adaptive instead of fixed:
- position structure changes (hard trigger) - position structure changes (hard trigger)
@@ -105,10 +111,10 @@ Recommended pattern:
7. For even lower spend, move the high-frequency cadence outside Hermes cron entirely: 7. For even lower spend, move the high-frequency cadence outside Hermes cron entirely:
- install a system `crontab` entry that runs a local gate script every 5-10 minutes - install a system `crontab` entry that runs a local gate script every 5-10 minutes
- let that gate script run the lightweight precheck - let that gate script run the lightweight precheck
- only when `should_analyze=true` and no run is already queued, trigger the Hermes cron job via `hermes cron run <job_id>` - only when `should_analyze=true` and no run is already queued, trigger your platform's cron job (e.g. `hermes cron run <job_id>` or `openclaw trigger <job_id>`)
- store a `run_requested_at` marker in `~/.coinhunter/state/precheck_state.json` and clear it when the analysis acknowledges completion - store a `run_requested_at` marker in `~/.coinhunter/state/precheck_state.json` and clear it when the analysis acknowledges completion
This pattern preserves Telegram auto-delivery from Hermes cron while reducing model wakeups to trigger-only events. 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 ### 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. - 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.
@@ -214,31 +220,51 @@ if __name__ == "__main__":
print(json.dumps(result)) print(json.dumps(result))
``` ```
#### 4. Hermes cron job configuration #### 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: Attach the precheck script as the `script` field of the cron job so its JSON output is injected into the prompt.
**Hermes example:**
```json ```json
{ {
"id": "coinhunter-trade", "id": "coinhunter-trade",
"schedule": "*/15 * * * *", "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.", "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_precheck.py", "script": "coinhunter_shim.py pre",
"deliver": "telegram", "deliver": "telegram",
"model": "kimi-for-coding" "model": "kimi-for-coding"
} }
``` ```
Add an `--ack` handler to the precheck script (or a separate ack script) that sets `run_acknowledged_at` and clears `run_requested_at` so the gate does not re-fire until the next true trigger. **OpenClaw example:**
```json
{
"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) #### 5. External gate (optional, for even lower cost)
If you want to run the precheck every 5 minutes without waking Hermes at all: If you want to run the precheck every 5 minutes without waking Hermes at all:
External gate pseudocode (run from `~/.hermes/scripts/`): External gate pseudocode (run from your platform's scripts directory):
```python ```python
import fcntl, os, subprocess, json, sys import fcntl, os, subprocess, json, sys
LOCK_PATH = os.path.expanduser("~/.coinhunter/state/external_gate.lock") LOCK_PATH = os.path.expanduser("~/.coinhunter/state/external_gate.lock")
PRECHECK = os.path.expanduser("~/.hermes/scripts/coinhunter_precheck.py")
JOB_ID = "coinhunter-trade" 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: with open(LOCK_PATH, "w") as f:
try: try:
@@ -246,22 +272,37 @@ with open(LOCK_PATH, "w") as f:
except BlockingIOError: except BlockingIOError:
sys.exit(0) # another instance is running sys.exit(0) # another instance is running
result = json.loads(os.popen(f"python {PRECHECK}").read()) result = json.loads(os.popen("coinhunter pre").read())
if result.get("should_analyze"): if result.get("should_analyze"):
# Trigger Hermes cron only if not already requested # Trigger platform cron only if not already requested
state_path = os.path.expanduser("~/.coinhunter/state/precheck_state.json") state_path = os.path.expanduser("~/.coinhunter/state/precheck_state.json")
state = json.load(open(state_path)) state = json.load(open(state_path))
if not state.get("run_requested_at"): if not state.get("run_requested_at"):
subprocess.run(["hermes", "cron", "run", JOB_ID], check=False) subprocess.run([*cron_command, JOB_ID], check=False)
``` ```
System crontab entry: System crontab entry:
```cron ```cron
*/5 * * * * /usr/bin/python3 /home/user/.hermes/scripts/coinhunter_external_gate.py >> /home/user/.coinhunter/logs/external_gate.log 2>&1 */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%. 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:
1. **`'PosixPath' object has no attribute 'env_file'`**
- Location: inside the installed `coinhunter` package (`src/coinhunter/services/market_data.py` in the PyPI source)
- Cause: `load_env_file(ENV_FILE)` is passed a `Path` object, but `load_env_file()` expects either a `RuntimePaths` dataclass or no arguments.
- Fix: Update `coinhunter` to the latest version from PyPI. If the bug persists, patch the installed package and submit an issue to the `coinhunter` project.
2. **`name 'BASE_PN_L_TRIGGER_PCT' is not defined`**
- Location: inside the installed `coinhunter` package (`src/coinhunter/services/adaptive_profile.py` in the PyPI source)
- Cause: Typo `BASE_PN_L_TRIGGER_PCT` instead of `BASE_PNL_TRIGGER_PCT`.
- Fix: Update `coinhunter` to the latest version from PyPI. If the bug persists, patch the installed package and submit an issue to the `coinhunter` project.
After updating, rerun `coinhunter pre` to verify the gate clears before executing the trading decision.
### Production hardening (mandatory) ### Production hardening (mandatory)
The live trading stack must include these safeguards: The live trading stack must include these safeguards:
1. **Idempotency** — every decision carries a `decision_id`. The executor checks `~/.coinhunter/executions.json` before submitting orders to prevent duplicate trades. 1. **Idempotency** — every decision carries a `decision_id`. The executor checks `~/.coinhunter/executions.json` before submitting orders to prevent duplicate trades.
@@ -272,6 +313,21 @@ The live trading stack must include these safeguards:
6. **Structured logging** — every decision, trade, error, and balance snapshot is written as JSONL under `~/.coinhunter/logs/` with `schema_version` and `decision_id`. 6. **Structured logging** — every decision, trade, error, and balance snapshot is written as JSONL under `~/.coinhunter/logs/` with `schema_version` and `decision_id`.
7. **Error logging** — failed API calls, rejected orders, and reconciliation mismatches are captured in `logs/errors_YYYYMMDD.jsonl` and fed into the hourly review. 7. **Error logging** — failed API calls, rejected orders, and reconciliation mismatches are captured in `logs/errors_YYYYMMDD.jsonl` and fed into the hourly review.
## Cross-platform deployment
Coin Hunter is runtime-agnostic. It works on Hermes, OpenClaw, and any compatible cron-based platform.
1. **Install the CLI** (same everywhere):
```bash
pipx install coinhunter
```
2. **Place the shim** in your platform's scripts directory:
- Hermes: `~/.hermes/scripts/coinhunter_shim.py`
- OpenClaw: `~/.openclaw/scripts/coinhunter_shim.py`
3. *(Optional)* Create `~/.coinhunter/platform.json` if 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 ## Safety rules
- No leverage/futures when capital < $200. - No leverage/futures when capital < $200.
- When capital < $50, concentrate into **1 position only**. - When capital < $50, concentrate into **1 position only**.

View File

@@ -2,7 +2,7 @@
Complete guide for building and running a hands-off meme-coin trading bot using the Binance Spot API. Complete guide for building and running a hands-off meme-coin trading bot using the Binance Spot API.
> Note: CoinHunter code now lives in `~/.hermes/skills/coinhunter/scripts/` and is preferably invoked via `coinhunter_cli.py`. Treat any references in this guide to runtime copies under `~/.coinhunter/` or shell wrappers like `run_trader.sh` as legacy structure notes unless explicitly updated below. > Note: The CoinHunter CLI is an external PyPI package (`pipx install coinhunter`). All execution goes through the `coinhunter` command. Treat any references in this guide to local source directories, `coinhunter_cli.py`, or shell wrappers like `run_trader.sh` as legacy structure notes unless explicitly updated below.
## Scope ## Scope
@@ -23,13 +23,15 @@ This guide covers:
## Architecture ## Architecture
> **Note:** The current architecture uses the external `coinhunter` CLI (installed from PyPI) plus thin platform shims. The legacy local files (`auto_trader.py`, `run_trader.sh`) noted below are historical references only.
``` ```
~/.coinhunter/ ~/.coinhunter/
├── auto_trader.py # Main trading logic ├── .env # API keys and secrets
├── run_trader.sh # Shell wrapper (venv + env vars + logging) ├── positions.json # Portfolio state (shared with coinhunter)
├── check_api.py # Quick API connectivity validator ├── state/ # Gate state and locks
├── logs/trader.log # Execution logs ├── logs/ # Execution logs
└── positions.json # Portfolio state (shared with coinhunter) └── reviews/ # Hourly review reports
``` ```
## Step 1: Binance API Key setup ## Step 1: Binance API Key setup
@@ -44,15 +46,17 @@ This guide covers:
- Use the public IP of the machine that will run the bot - Use the public IP of the machine that will run the bot
- This prevents key reuse if the credential is ever leaked - This prevents key reuse if the credential is ever leaked
**Security reminder:** never paste API keys into chat messages. Write them directly into `~/.hermes/.env`. **Security reminder:** never paste API keys into chat messages. Write them into your platform's environment file (e.g. `~/.hermes/.env` or `~/.openclaw/.env`). You can also store them under `~/.coinhunter/.env` and source that file in your wrapper script.
## Step 2: Store credentials ## Step 2: Store credentials
Append to `~/.hermes/.env`: Append to your environment file (check `platform.json` -> `env_file` if you have one, otherwise use your platform default):
```env ```bash
cat >> ~/.coinhunter/.env << 'EOF'
BINANCE_API_KEY=your_api_key_here BINANCE_API_KEY=your_api_key_here
BINANCE_API_SECRET=your_api_secret_here BINANCE_API_SECRET=your_api_secret_here
EOF
``` ```
## Step 3: Install dependencies ## Step 3: Install dependencies
@@ -72,46 +76,33 @@ pip install ccxt pandas numpy
## Step 4: Deploy the bot ## Step 4: Deploy the bot
Use `scripts/auto_trader.py` from the coinhunter skill as the template. Copy it into the user's `~/.coinhunter/` directory and customize: The trading logic is provided by the external `coinhunter` CLI. To run it automatically, deploy the platform shim and a small wrapper script.
- `MAX_POSITIONS` — max concurrent meme-coin positions (default 2) If you need custom parameters (max positions, allocation percentage, stop-loss levels), configure them in `~/.coinhunter/config.json` and reference them from your wrapper script, or pass them as flags to `coinhunter exec`.
- `CAPITAL_ALLOCATION_PCT` — fraction of total USDT to use (default 0.95; leave ~5% buffer for fees/slippage)
- `MIN_POSITION_USDT` — minimum single order size (default 50)
- `STOP_LOSS_PCT` / `TAKE_PROFIT_1_PCT` / `TAKE_PROFIT_2_PCT` — risk levels
Create `run_trader.sh`: Example wrapper (`run_trader.sh`):
```bash ```bash
#!/bin/bash #!/bin/bash
set -e set -e
cd "$(dirname "$0")" cd "$(dirname "$0")"
python3 check_api.py source ~/.coinhunter/.env
source /path/to/venv/bin/activate source /path/to/venv/bin/activate
export DRY_RUN=${DRY_RUN:-true} export DRY_RUN=${DRY_RUN:-true}
python3 auto_trader.py >> logs/trader.log 2>&1 coinhunter exec >> logs/trader.log 2>&1
``` ```
Make executable: Make executable:
```bash ```bash
chmod +x run_trader.sh check_api.py chmod +x run_trader.sh
mkdir -p logs mkdir -p logs
``` ```
## Step 5: Validate API connectivity ## Step 5: Run a DRY_RUN test
```bash ```bash
python3 check_api.py DRY_RUN=true coinhunter exec
```
Expected output: `✅ API 配置正常`
If this fails, the bot will exit immediately on each run.
## Step 6: Run a DRY_RUN test
```bash
DRY_RUN=true python3 auto_trader.py
``` ```
Expected behavior: Expected behavior:
@@ -123,9 +114,9 @@ Expected behavior:
Only proceed to live trading after at least one dry-run cycle completes without errors. Only proceed to live trading after at least one dry-run cycle completes without errors.
## Step 7: Schedule with cronjob ## Step 6: Schedule with your platform's cron system
Use the `cronjob` tool to run the bot every 15 minutes: **Hermes example:**
```json ```json
{ {
@@ -137,7 +128,19 @@ Use the `cronjob` tool to run the bot every 15 minutes:
} }
``` ```
## Step 8: Switch to live trading **OpenClaw example:**
```json
{
"action": "create",
"name": "Coin Hunter Auto Trader",
"schedule": "*/15 * * * *",
"deliver": "webhook",
"prompt": "Run the Coin Hunter automatic meme-coin trading bot.\n1. cd /home/<user>/.coinhunter\n2. ./run_trader.sh\n3. Summarize actions and report back."
}
```
## Step 7: Switch to live trading
Once DRY_RUN validation succeeds and the user confirms: Once DRY_RUN validation succeeds and the user confirms:
@@ -151,7 +154,7 @@ Once DRY_RUN validation succeeds and the user confirms:
1. **Never enable Withdrawal permission** on the API key. 1. **Never enable Withdrawal permission** on the API key.
2. **Always bind an IP whitelist** if possible. 2. **Always bind an IP whitelist** if possible.
3. **Never accept API keys in plaintext chat.** Ask the user to write them into `~/.hermes/.env`. 3. **Never accept API keys in plaintext chat.** Ask the user to write them into their platform environment file (e.g. `~/.hermes/.env` or `~/.openclaw/.env`) or `~/.coinhunter/.env`.
4. **Do not set allocation to exactly 100%.** Leave at least 35% buffer for fees and slippage. 4. **Do not set allocation to exactly 100%.** Leave at least 35% buffer for fees and slippage.
5. **Start with DRY_RUN.** Run at least one full cycle before going live. 5. **Start with DRY_RUN.** Run at least one full cycle before going live.
6. **Check the account balance first.** If USDT is 0 (or held in Earn/Margin/Futures), the bot cannot trade. 6. **Check the account balance first.** If USDT is 0 (or held in Earn/Margin/Futures), the bot cannot trade.
@@ -172,10 +175,10 @@ ticker = tickers.get(sym_ccxt)
### .env file is protected ### .env file is protected
The `patch` tool may reject edits to `~/.hermes/.env`. Use terminal redirection instead: The `patch` tool may reject edits to environment files. Use terminal redirection instead:
```bash ```bash
cat >> ~/.hermes/.env << 'EOF' cat >> ~/.coinhunter/.env << 'EOF'
BINANCE_API_KEY=xxx BINANCE_API_KEY=xxx
BINANCE_API_SECRET=yyy BINANCE_API_SECRET=yyy
EOF EOF

View File

@@ -1,16 +1,33 @@
# CoinHunter shim templates # CoinHunter shim templates
These files are tiny compatibility shims for Hermes platform features that currently expect scripts under `~/.hermes/scripts/`. These files are tiny compatibility shims for cron-based platforms (Hermes, OpenClaw, etc.) that expect scripts under a scripts directory such as `~/.hermes/scripts/` or `~/.openclaw/scripts/`.
When needed, copy them like this: ## Unified shim (recommended)
`templates/coinhunter_shim.py` is the cross-platform wrapper. It takes the subcommand as its first argument and delegates to the installed `coinhunter` CLI:
```bash
cp templates/coinhunter_shim.py ~/.hermes/scripts/coinhunter_shim.py
# or
cp templates/coinhunter_shim.py ~/.openclaw/scripts/coinhunter_shim.py
```
Usage examples:
- `coinhunter_shim.py pre`
- `coinhunter_shim.py gate`
- `coinhunter_shim.py review`
- `coinhunter_shim.py rotate-log`
## Legacy shims (backward compatibility)
The original individual shims are still provided for existing Hermes users who already have them deployed. Their behavior is unchanged:
- `templates/coinhunter_precheck_shim.py` -> `~/.hermes/scripts/coinhunter_precheck.py` - `templates/coinhunter_precheck_shim.py` -> `~/.hermes/scripts/coinhunter_precheck.py`
- `templates/coinhunter_external_gate_shim.py` -> `~/.hermes/scripts/coinhunter_external_gate.py` - `templates/coinhunter_external_gate_shim.py` -> `~/.hermes/scripts/coinhunter_external_gate.py`
- `templates/coinhunter_review_context_shim.py` -> `~/.hermes/scripts/coinhunter_review_context.py` - `templates/coinhunter_review_context_shim.py` -> `~/.hermes/scripts/coinhunter_review_context.py`
- `templates/rotate_external_gate_log_shim.sh` -> `~/.hermes/scripts/rotate_external_gate_log.sh` - `templates/rotate_external_gate_log_shim.py` -> `~/.hermes/scripts/rotate_external_gate_log.py`
The real business logic stays inside the skill under: The real business logic lives in the external `coinhunter` CLI package (installed from PyPI). These shims only delegate to it.
- `~/.hermes/skills/coinhunter/scripts/`
The user runtime data stays under: The user runtime data stays under:
- `~/.coinhunter/` - `~/.coinhunter/`

View File

@@ -17,6 +17,7 @@ This keeps personal accounts, positions, and watchlists out of packaged skill ar
```text ```text
~/.coinhunter/ ~/.coinhunter/
├── config.json ├── config.json
├── platform.json
├── accounts.json ├── accounts.json
├── positions.json ├── positions.json
├── watchlist.json ├── watchlist.json
@@ -46,6 +47,28 @@ Example:
} }
``` ```
### platform.json
Optional cross-platform runtime configuration. When absent, the framework defaults to Hermes behavior.
Suggested fields:
- `platform` — runtime name (`"hermes"` or `"openclaw"`)
- `scripts_dir` — where platform shims are deployed
- `env_file` — path to the environment file for secrets
- `cron_command` — command array used by the external gate to trigger a job
- `delivery` — default delivery channel (`"telegram"`, `"webhook"`, etc.)
Example:
```json
{
"platform": "openclaw",
"scripts_dir": "~/.openclaw/scripts",
"env_file": "~/.openclaw/.env",
"cron_command": ["openclaw", "trigger"],
"delivery": "webhook"
}
```
### accounts.json ### accounts.json
Store exchange accounts and balances. Store exchange accounts and balances.

View File

@@ -1,10 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Compatibility shim for external gate execution. """Hermes cron shim: runs coinhunter external-gate via CLI."""
Real logic lives in the CoinHunter skill. import shutil
Copy this file to ~/.hermes/scripts/coinhunter_external_gate.py if needed. import subprocess
""" import sys
import runpy
from pathlib import Path
TARGET = Path.home() / ".hermes" / "skills" / "coinhunter" / "scripts" / "coinhunter_external_gate.py" BIN = shutil.which("coinhunter") or shutil.which("coinhunter.exe")
runpy.run_path(str(TARGET), run_name="__main__") if not BIN:
print("error: coinhunter CLI not found in PATH. Install with: pipx install coinhunter", file=sys.stderr)
sys.exit(127)
sys.exit(subprocess.run([BIN, "gate", *sys.argv[1:]]).returncode)

View File

@@ -1,10 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Compatibility shim for Hermes cron script hook. """Hermes cron shim: runs coinhunter precheck via CLI."""
Real logic lives in the CoinHunter skill. import shutil
Copy this file to ~/.hermes/scripts/coinhunter_precheck.py if needed. import subprocess
""" import sys
import runpy
from pathlib import Path
TARGET = Path.home() / ".hermes" / "skills" / "coinhunter" / "scripts" / "coinhunter_precheck.py" BIN = shutil.which("coinhunter") or shutil.which("coinhunter.exe")
runpy.run_path(str(TARGET), run_name="__main__") if not BIN:
print("error: coinhunter CLI not found in PATH. Install with: pipx install coinhunter", file=sys.stderr)
sys.exit(127)
sys.exit(subprocess.run([BIN, "pre", *sys.argv[1:]]).returncode)

View File

@@ -1,10 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Compatibility shim for review-context cron script hook. """Hermes cron shim: runs coinhunter review-context via CLI."""
Real logic lives in the CoinHunter skill. import shutil
Copy this file to ~/.hermes/scripts/coinhunter_review_context.py if needed. import subprocess
""" import sys
import runpy
from pathlib import Path
TARGET = Path.home() / ".hermes" / "skills" / "coinhunter" / "scripts" / "coinhunter_review_context.py" BIN = shutil.which("coinhunter") or shutil.which("coinhunter.exe")
runpy.run_path(str(TARGET), run_name="__main__") if not BIN:
print("error: coinhunter CLI not found in PATH. Install with: pipx install coinhunter", file=sys.stderr)
sys.exit(127)
sys.exit(subprocess.run([BIN, "review", *sys.argv[1:]]).returncode)

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env python3
"""Cross-platform cron shim: delegates any coinhunter subcommand via CLI."""
import shutil
import subprocess
import sys
BIN = shutil.which("coinhunter") or shutil.which("coinhunter.exe")
if not BIN:
print(
"error: coinhunter CLI not found in PATH. Install with: pipx install coinhunter",
file=sys.stderr,
)
sys.exit(127)
if len(sys.argv) < 2:
print("usage: coinhunter_shim.py <subcommand> [args...]", file=sys.stderr)
print("example: coinhunter_shim.py pre", file=sys.stderr)
sys.exit(2)
subcommand = sys.argv[1]
args = sys.argv[2:]
sys.exit(subprocess.run([BIN, subcommand, *args]).returncode)

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env python3
"""Hermes cron shim: runs coinhunter rotate-log via CLI."""
import shutil
import subprocess
import sys
BIN = shutil.which("coinhunter") or shutil.which("coinhunter.exe")
if not BIN:
print("error: coinhunter CLI not found in PATH. Install with: pipx install coinhunter", file=sys.stderr)
sys.exit(127)
sys.exit(subprocess.run([BIN, "rotate-log", *sys.argv[1:]]).returncode)

View File

@@ -1,3 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
python3 "$HOME/.hermes/skills/coinhunter/scripts/rotate_external_gate_log.py"