diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..0f4a384 --- /dev/null +++ b/CLAUDE.md @@ -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. diff --git a/README.md b/README.md index 8a90e1e..b648a56 100644 --- a/README.md +++ b/README.md @@ -37,29 +37,30 @@ ```mermaid flowchart TD - A[System crontab
every 5 min] -->|local python| B[External Gate] + A[System crontab
every 5 min] -->|coinhunter gate| B[External Gate] B --> C{should_analyze?} C -->|No| D[Silent exit
zero cost] - C -->|Yes| E[Trigger Hermes cron] + C -->|Yes| E[Trigger platform cron] E --> F[LLM Deep Analysis] - F --> G[smart_executor.py] + F --> G[coinhunter exec] G --> H[Binance API] - F --> I[logger.py] + F --> I[coinhunter logs] I --> J[~/.coinhunter/logs/] - K[review_engine.py
hourly] --> J + K[coinhunter recap
hourly] --> J ``` ### Key components -| File | Purpose | -|------|---------| -| `scripts/market_probe.py` | Market data fetcher (ccxt + web search) | -| `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 | -| `scripts/coinhunter_cli.py` | Unified CLI entrypoint for CoinHunter operations | -| `scripts/smart_executor.py` | Order execution layer with idempotency & precision validation | -| `scripts/logger.py` | Structured JSONL logging of every decision & trade | -| `scripts/review_engine.py` | Hourly quality review & parameter optimization | +All operations go through the installed `coinhunter` CLI. This skill provides the framework specification, reference playbooks, and Hermes cron shims. + +| Command | Purpose | +|---------|---------| +| `coinhunter probe` | Market data fetcher (ccxt + web search) | +| `coinhunter pre` | **Lightweight gate** — computes adaptive thresholds and decides if analysis is needed | +| `coinhunter gate` | Optional **system-crontab wrapper** that runs the gate entirely outside Hermes | +| `coinhunter exec` | Order execution layer with idempotency & precision validation | +| `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 ``` -### 2. Set up your runtime directory +### 2. Install the CLI tool ```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`: @@ -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`. -It is ~100 lines of pure Python: reads your state, hashes positions, checks adaptive price/PnL thresholds, and outputs a tiny JSON decision. +**Option A — unified shim (recommended for new setups and cross-platform):** -### 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 { "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": "~/.hermes/scripts/coinhunter_precheck.py", + "script": "coinhunter_shim.py pre", "deliver": "telegram", "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 -*/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/ ├── README.md # You are here ├── SKILL.md # Full framework spec + gate blueprint -├── scripts/ -│ ├── market_probe.py # Market data fetcher -│ ├── init_user_state.py # Bootstrap helper -│ ├── auto_trader.py # Reference trading loop -│ └── ... # Your gate scripts live in ~/.hermes/scripts/ +├── CLAUDE.md # Guidance for Claude Code +├── templates/ # Platform cron shims (call the installed coinhunter CLI) +│ ├── coinhunter_shim.py # Unified cross-platform shim (recommended) +│ ├── coinhunter_precheck_shim.py +│ ├── coinhunter_external_gate_shim.py +│ ├── coinhunter_review_context_shim.py +│ └── rotate_external_gate_log_shim.py └── references/ ├── short-term-trading-framework.md ├── review-template.md diff --git a/SKILL.md b/SKILL.md index 2d84b36..dd59abf 100644 --- a/SKILL.md +++ b/SKILL.md @@ -76,6 +76,12 @@ Read `references/short-term-trading-framework.md` before every active decision p ## Auto-trading architecture +Install the executable CLI first: +```bash +pipx install coinhunter +# or: pip install coinhunter +``` + | CLI Command | Purpose | |-------------|---------| | `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. 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/`. 3. Trigger full analysis only when one of these changes materially. Make the thresholds adaptive instead of fixed: - 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: - install a system `crontab` entry that runs a local gate script every 5-10 minutes - 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 ` + - only when `should_analyze=true` and no run is already queued, trigger your platform's cron job (e.g. `hermes cron run ` or `openclaw trigger `) - 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 - 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)) ``` -#### 4. Hermes cron job configuration -Attach the precheck script as the `script` field of the cron job so its JSON output is injected into the prompt: +#### 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:** ```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_precheck.py", + "script": "coinhunter_shim.py pre", "deliver": "telegram", "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) 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 import fcntl, os, subprocess, json, sys LOCK_PATH = os.path.expanduser("~/.coinhunter/state/external_gate.lock") -PRECHECK = os.path.expanduser("~/.hermes/scripts/coinhunter_precheck.py") 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: @@ -246,22 +272,37 @@ with open(LOCK_PATH, "w") as f: except BlockingIOError: 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"): - # 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 = json.load(open(state_path)) 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: ```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%. +### 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) 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. @@ -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`. 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 - No leverage/futures when capital < $200. - When capital < $50, concentrate into **1 position only**. diff --git a/references/auto-trading-guide.md b/references/auto-trading-guide.md index 8e4bb41..740c1c3 100644 --- a/references/auto-trading-guide.md +++ b/references/auto-trading-guide.md @@ -2,7 +2,7 @@ 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 @@ -23,13 +23,15 @@ This guide covers: ## 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/ -├── auto_trader.py # Main trading logic -├── run_trader.sh # Shell wrapper (venv + env vars + logging) -├── check_api.py # Quick API connectivity validator -├── logs/trader.log # Execution logs -└── positions.json # Portfolio state (shared with coinhunter) +├── .env # API keys and secrets +├── positions.json # Portfolio state (shared with coinhunter) +├── state/ # Gate state and locks +├── logs/ # Execution logs +└── reviews/ # Hourly review reports ``` ## 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 - 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 -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_SECRET=your_api_secret_here +EOF ``` ## Step 3: Install dependencies @@ -72,46 +76,33 @@ pip install ccxt pandas numpy ## 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) -- `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 +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`. -Create `run_trader.sh`: +Example wrapper (`run_trader.sh`): ```bash #!/bin/bash set -e cd "$(dirname "$0")" -python3 check_api.py +source ~/.coinhunter/.env source /path/to/venv/bin/activate export DRY_RUN=${DRY_RUN:-true} -python3 auto_trader.py >> logs/trader.log 2>&1 +coinhunter exec >> logs/trader.log 2>&1 ``` Make executable: ```bash -chmod +x run_trader.sh check_api.py +chmod +x run_trader.sh mkdir -p logs ``` -## Step 5: Validate API connectivity +## Step 5: Run a DRY_RUN test ```bash -python3 check_api.py -``` - -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 +DRY_RUN=true coinhunter exec ``` Expected behavior: @@ -123,9 +114,9 @@ Expected behavior: 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 { @@ -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//.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: @@ -151,7 +154,7 @@ Once DRY_RUN validation succeeds and the user confirms: 1. **Never enable Withdrawal permission** on the API key. 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 3–5% buffer for fees and slippage. 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. @@ -172,10 +175,10 @@ ticker = tickers.get(sym_ccxt) ### .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 -cat >> ~/.hermes/.env << 'EOF' +cat >> ~/.coinhunter/.env << 'EOF' BINANCE_API_KEY=xxx BINANCE_API_SECRET=yyy EOF diff --git a/references/shim-templates.md b/references/shim-templates.md index 783d728..7e9fa5e 100644 --- a/references/shim-templates.md +++ b/references/shim-templates.md @@ -1,16 +1,33 @@ # 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_external_gate_shim.py` -> `~/.hermes/scripts/coinhunter_external_gate.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: -- `~/.hermes/skills/coinhunter/scripts/` +The real business logic lives in the external `coinhunter` CLI package (installed from PyPI). These shims only delegate to it. The user runtime data stays under: - `~/.coinhunter/` diff --git a/references/user-data-layout.md b/references/user-data-layout.md index 84d129e..0963a87 100644 --- a/references/user-data-layout.md +++ b/references/user-data-layout.md @@ -17,6 +17,7 @@ This keeps personal accounts, positions, and watchlists out of packaged skill ar ```text ~/.coinhunter/ ├── config.json +├── platform.json ├── accounts.json ├── positions.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 Store exchange accounts and balances. diff --git a/templates/coinhunter_external_gate_shim.py b/templates/coinhunter_external_gate_shim.py index 07bd97f..04df070 100644 --- a/templates/coinhunter_external_gate_shim.py +++ b/templates/coinhunter_external_gate_shim.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 -"""Compatibility shim for external gate execution. -Real logic lives in the CoinHunter skill. -Copy this file to ~/.hermes/scripts/coinhunter_external_gate.py if needed. -""" -import runpy -from pathlib import Path +"""Hermes cron shim: runs coinhunter external-gate via CLI.""" +import shutil +import subprocess +import sys -TARGET = Path.home() / ".hermes" / "skills" / "coinhunter" / "scripts" / "coinhunter_external_gate.py" -runpy.run_path(str(TARGET), run_name="__main__") +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, "gate", *sys.argv[1:]]).returncode) diff --git a/templates/coinhunter_precheck_shim.py b/templates/coinhunter_precheck_shim.py index 75bc6f4..f241bdd 100644 --- a/templates/coinhunter_precheck_shim.py +++ b/templates/coinhunter_precheck_shim.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 -"""Compatibility shim for Hermes cron script hook. -Real logic lives in the CoinHunter skill. -Copy this file to ~/.hermes/scripts/coinhunter_precheck.py if needed. -""" -import runpy -from pathlib import Path +"""Hermes cron shim: runs coinhunter precheck via CLI.""" +import shutil +import subprocess +import sys -TARGET = Path.home() / ".hermes" / "skills" / "coinhunter" / "scripts" / "coinhunter_precheck.py" -runpy.run_path(str(TARGET), run_name="__main__") +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, "pre", *sys.argv[1:]]).returncode) diff --git a/templates/coinhunter_review_context_shim.py b/templates/coinhunter_review_context_shim.py index 0db6680..0220f34 100644 --- a/templates/coinhunter_review_context_shim.py +++ b/templates/coinhunter_review_context_shim.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 -"""Compatibility shim for review-context cron script hook. -Real logic lives in the CoinHunter skill. -Copy this file to ~/.hermes/scripts/coinhunter_review_context.py if needed. -""" -import runpy -from pathlib import Path +"""Hermes cron shim: runs coinhunter review-context via CLI.""" +import shutil +import subprocess +import sys -TARGET = Path.home() / ".hermes" / "skills" / "coinhunter" / "scripts" / "coinhunter_review_context.py" -runpy.run_path(str(TARGET), run_name="__main__") +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, "review", *sys.argv[1:]]).returncode) diff --git a/templates/coinhunter_shim.py b/templates/coinhunter_shim.py new file mode 100644 index 0000000..bc7751e --- /dev/null +++ b/templates/coinhunter_shim.py @@ -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 [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) diff --git a/templates/rotate_external_gate_log_shim.py b/templates/rotate_external_gate_log_shim.py new file mode 100644 index 0000000..980a261 --- /dev/null +++ b/templates/rotate_external_gate_log_shim.py @@ -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) diff --git a/templates/rotate_external_gate_log_shim.sh b/templates/rotate_external_gate_log_shim.sh deleted file mode 100644 index e61dcc1..0000000 --- a/templates/rotate_external_gate_log_shim.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail -python3 "$HOME/.hermes/skills/coinhunter/scripts/rotate_external_gate_log.py"