refactor: rewrite to CoinHunter V2 flat architecture
Replace the V1 commands/services split with a flat, direct architecture: - cli.py dispatches directly to service functions - New services: account, market, trade, opportunity - Thin Binance wrappers: spot_client, um_futures_client - Add audit logging, runtime paths, and TOML config - Remove legacy V1 code: commands/, precheck, review engine, smart executor - Add ruff + mypy toolchain and fix edge cases in trade params Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
339
README.md
339
README.md
@@ -3,318 +3,111 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://readme-typing-svg.demolab.com?font=JetBrains+Mono&weight=500&size=22&duration=2800&pause=800&color=F7B93E¢er=true&vCenter=true&width=600&lines=Spot+Trading+Orchestration+for+Terminal+Cowboys;Precheck+%E2%86%92+Execute+%E2%86%92+Review+%E2%86%92+Repeat;JSON-first+CLI+with+Dry-run+Safety" alt="Typing SVG" />
|
||||
<img src="https://readme-typing-svg.demolab.com?font=JetBrains+Mono&weight=500&size=22&duration=2800&pause=800&color=F7B93E¢er=true&vCenter=true&width=600&lines=Binance-first+Trading+CLI;Account+%E2%86%92+Market+%E2%86%92+Trade+%E2%86%92+Opportunity;JSON-first+with+Dry-run+Safety" alt="Typing SVG" />
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>Runtime-safe trading operations, precheck orchestration, review tooling, and market probes.</strong>
|
||||
<strong>A Binance-first crypto trading CLI for balances, market data, opportunity scanning, and execution.</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://pypi.org/project/coinhunter/"><img src="https://img.shields.io/pypi/v/coinhunter?style=flat-square&color=F7B93E&labelColor=1a1a1a" /></a>
|
||||
<a href="#"><img src="https://img.shields.io/badge/python-3.10%2B-3776ab?style=flat-square&logo=python&logoColor=white&labelColor=1a1a1a" /></a>
|
||||
<a href="#"><img src="https://img.shields.io/badge/tests-96%20passed-22c55e?style=flat-square&labelColor=1a1a1a" /></a>
|
||||
<a href="#"><img src="https://img.shields.io/badge/tests-passing-22c55e?style=flat-square&labelColor=1a1a1a" /></a>
|
||||
<a href="#"><img src="https://img.shields.io/badge/lint-ruff%20%2B%20mypy-8b5cf6?style=flat-square&labelColor=1a1a1a" /></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## What is this?
|
||||
|
||||
`coinhunter` is the **executable tooling layer** for CoinHunter — an installable Python CLI that handles trading operations, market probes, precheck orchestration, and review workflows.
|
||||
|
||||
> **Note:** The old package name `coinhunter-cli` is deprecated. Please install `coinhunter` going forward.
|
||||
|
||||
| Layer | Responsibility | Location |
|
||||
|-------|----------------|----------|
|
||||
| **CLI** | Top-level command router | `cli.py` |
|
||||
| **Commands** | Thin argument adapters | `commands/` |
|
||||
| **Services** | Orchestration & execution logic | `services/` |
|
||||
| **Runtime** | Paths, env, locks, config | `runtime.py` |
|
||||
| **User Data** | State, logs, reviews, positions | `~/.coinhunter/` |
|
||||
|
||||
> **Separation of concerns:** Code lives in this repo. Your data lives in `~/.coinhunter/`. Strategy and prompting live in Hermes skills.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```text
|
||||
src/coinhunter/
|
||||
├── cli.py # Unified command router
|
||||
├── runtime.py # Runtime paths + env loading
|
||||
├── logger.py # Structured logging utilities
|
||||
├── commands/ # CLI adapters (thin, stateless)
|
||||
│ ├── precheck.py
|
||||
│ ├── smart_executor.py
|
||||
│ ├── check_api.py
|
||||
│ ├── doctor.py
|
||||
│ ├── external_gate.py
|
||||
│ ├── init_user_state.py
|
||||
│ ├── market_probe.py
|
||||
│ ├── paths.py
|
||||
│ ├── review_context.py
|
||||
│ ├── review_engine.py
|
||||
│ └── rotate_external_gate_log.py
|
||||
├── services/ # Orchestration & domain logic
|
||||
│ ├── exchange_service.py
|
||||
│ ├── portfolio_service.py
|
||||
│ ├── trade_execution.py
|
||||
│ ├── smart_executor_service.py
|
||||
│ ├── smart_executor_parser.py
|
||||
│ ├── execution_state.py
|
||||
│ ├── precheck_service.py
|
||||
│ ├── review_service.py # review generation logic
|
||||
│ ├── precheck_constants.py # thresholds
|
||||
│ ├── time_utils.py # UTC/local time helpers
|
||||
│ ├── data_utils.py # json, hash, float, symbol norm
|
||||
│ ├── state_manager.py # state load/save/sanitize
|
||||
│ ├── market_data.py # exchange, OHLCV, metrics
|
||||
│ ├── candidate_scoring.py # coin selection & scoring
|
||||
│ ├── snapshot_builder.py # precheck snapshot construction
|
||||
│ ├── adaptive_profile.py # trigger profile builder
|
||||
│ ├── trigger_analyzer.py # trigger analysis core
|
||||
│ ├── precheck_analysis.py # failure payloads
|
||||
│ ├── precheck_snapshot.py # snapshot facade
|
||||
│ ├── precheck_state.py # state facade
|
||||
│ └── precheck_core.py # backward-compat export facade
|
||||
├── precheck.py # Backward-compat root facade
|
||||
├── smart_executor.py # Backward-compat root facade
|
||||
└── *.py # Other compat / utility modules
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### From PyPI (recommended)
|
||||
|
||||
`coinhunter` is a standalone CLI application. Use [pipx](https://pypa.github.io/pipx/) to install it in an isolated environment:
|
||||
|
||||
```bash
|
||||
pipx install coinhunter
|
||||
```
|
||||
|
||||
This installs the latest stable release and creates the `coinhunter` console script entry point.
|
||||
|
||||
Verify:
|
||||
|
||||
```bash
|
||||
coinhunter --help
|
||||
coinhunter --version
|
||||
```
|
||||
|
||||
> On newer Linux distributions, installing directly into the system Python with `pip install coinhunter` will fail with `externally-managed-environment`. Use `pipx` or a virtual environment instead.
|
||||
|
||||
### Development install (editable)
|
||||
|
||||
If you're working on this repo locally:
|
||||
## Install
|
||||
|
||||
```bash
|
||||
pip install -e ".[dev]"
|
||||
coinhunter --help
|
||||
```
|
||||
|
||||
Or use the convenience script:
|
||||
|
||||
```bash
|
||||
./scripts/install_local.sh
|
||||
```
|
||||
|
||||
A thin wrapper that runs `pip install -e .` and verifies the entrypoint is on your PATH.
|
||||
|
||||
---
|
||||
|
||||
## Command Reference
|
||||
|
||||
### Short aliases (recommended)
|
||||
|
||||
```bash
|
||||
coinhunter diag # runtime diagnostics
|
||||
coinhunter paths # print resolved paths
|
||||
coinhunter api-check # validate exchange credentials
|
||||
coinhunter precheck # run precheck snapshot + trigger analysis
|
||||
coinhunter exec bal # print balances as JSON
|
||||
coinhunter exec overview # account overview as JSON
|
||||
coinhunter exec hold # record a HOLD decision
|
||||
coinhunter exec buy ENJUSDT 50 # buy $50 of ENJUSDT
|
||||
coinhunter exec flat ENJUSDT # sell entire ENJUSDT position
|
||||
coinhunter exec rotate PEPEUSDT ETHUSDT # rotate exposure
|
||||
coinhunter exec orders # list open spot orders
|
||||
coinhunter exec order-status ENJUSDT 123456 # check specific order
|
||||
coinhunter exec cancel ENJUSDT 123456 # cancel an open order
|
||||
coinhunter gate # external gate orchestration
|
||||
coinhunter review 12 # generate review context (last 12h)
|
||||
coinhunter recap 12 # generate review report (last 12h)
|
||||
coinhunter probe bybit-ticker BTCUSDT # market probe
|
||||
coinhunter rotate-log # rotate external gate logs
|
||||
```
|
||||
|
||||
### Legacy long forms (still supported)
|
||||
|
||||
```bash
|
||||
coinhunter doctor
|
||||
coinhunter check-api
|
||||
coinhunter smart-executor bal
|
||||
coinhunter review-context 12
|
||||
coinhunter review-engine 12
|
||||
coinhunter market-probe bybit-ticker BTCUSDT
|
||||
coinhunter external-gate
|
||||
coinhunter rotate-external-gate-log
|
||||
```
|
||||
|
||||
### All supported commands
|
||||
|
||||
| Canonical | Aliases |
|
||||
|-----------|---------|
|
||||
| `check-api` | `api-check` |
|
||||
| `doctor` | `diag` |
|
||||
| `external-gate` | `gate` |
|
||||
| `init` | — |
|
||||
| `market-probe` | `probe` |
|
||||
| `paths` | — |
|
||||
| `precheck` | — |
|
||||
| `review-context` | `review` |
|
||||
| `review-engine` | `recap` |
|
||||
| `rotate-external-gate-log` | `rotate-gate-log`, `rotate-log` |
|
||||
| `smart-executor` | `exec` |
|
||||
|
||||
---
|
||||
|
||||
## Quickstart
|
||||
|
||||
Initialize runtime state:
|
||||
## Initialize runtime
|
||||
|
||||
```bash
|
||||
coinhunter init
|
||||
coinhunter init --force
|
||||
```
|
||||
|
||||
Inspect the environment:
|
||||
This creates:
|
||||
|
||||
- `~/.coinhunter/config.toml`
|
||||
- `~/.coinhunter/.env`
|
||||
- `~/.coinhunter/logs/`
|
||||
|
||||
`config.toml` stores runtime and strategy settings. `.env` stores:
|
||||
|
||||
```bash
|
||||
coinhunter paths
|
||||
coinhunter diag
|
||||
BINANCE_API_KEY=
|
||||
BINANCE_API_SECRET=
|
||||
```
|
||||
|
||||
Validate API keys:
|
||||
Override the default home directory with `COINHUNTER_HOME`.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
coinhunter api-check
|
||||
# Account
|
||||
coinhunter account overview
|
||||
coinhunter account balances --spot --futures
|
||||
coinhunter account positions --spot
|
||||
|
||||
# Market
|
||||
coinhunter market tickers BTCUSDT ETH/USDT sol-usdt
|
||||
coinhunter market klines BTCUSDT ETHUSDT --interval 1h --limit 50
|
||||
|
||||
# Trade (Spot)
|
||||
coinhunter trade spot buy BTCUSDT --quote 100 --dry-run
|
||||
coinhunter trade spot sell BTCUSDT --qty 0.01 --type limit --price 90000
|
||||
|
||||
# Trade (Futures)
|
||||
coinhunter trade futures buy BTCUSDT --qty 0.01 --dry-run
|
||||
coinhunter trade futures sell BTCUSDT --qty 0.01 --reduce-only
|
||||
coinhunter trade futures close BTCUSDT
|
||||
|
||||
# Opportunities
|
||||
coinhunter opportunity portfolio
|
||||
coinhunter opportunity scan
|
||||
coinhunter opportunity scan --symbols BTCUSDT ETHUSDT SOLUSDT
|
||||
```
|
||||
|
||||
Run the precheck workflow:
|
||||
## Architecture
|
||||
|
||||
```bash
|
||||
coinhunter precheck
|
||||
coinhunter precheck --ack "analysis completed"
|
||||
```
|
||||
CoinHunter V2 uses a flat, direct architecture:
|
||||
|
||||
Run the external gate:
|
||||
| Layer | Responsibility | Key Files |
|
||||
|-------|----------------|-----------|
|
||||
| **CLI** | Single entrypoint, argument parsing | `cli.py` |
|
||||
| **Binance** | Thin API wrappers with unified error handling | `binance/spot_client.py`, `binance/um_futures_client.py` |
|
||||
| **Services** | Domain logic | `services/account_service.py`, `services/market_service.py`, `services/trade_service.py`, `services/opportunity_service.py` |
|
||||
| **Config** | TOML config, `.env` secrets, path resolution | `config.py` |
|
||||
| **Runtime** | Paths, JSON helpers | `runtime.py` |
|
||||
| **Audit** | Structured JSONL logging | `audit.py` |
|
||||
|
||||
```bash
|
||||
coinhunter gate
|
||||
```
|
||||
## Logging
|
||||
|
||||
The gate reads `trigger_command` from `~/.coinhunter/config.json` under `external_gate`.
|
||||
- By default, no external trigger is configured — gate runs precheck and marks state, then exits cleanly.
|
||||
- Set `trigger_command` to a command list to integrate with your own scheduler:
|
||||
|
||||
```json
|
||||
{
|
||||
"external_gate": {
|
||||
"trigger_command": ["hermes", "cron", "run", "JOB_ID"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Set to `null` or `[]` to explicitly disable the external trigger.
|
||||
|
||||
### Dynamic tuning via `config.json`
|
||||
|
||||
You can override internal defaults without editing code by adding keys to `~/.coinhunter/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"external_gate": {
|
||||
"trigger_command": ["hermes", "cron", "run", "JOB_ID"]
|
||||
},
|
||||
"exchange": {
|
||||
"min_quote_volume": 200000,
|
||||
"cache_ttl_seconds": 3600
|
||||
},
|
||||
"logging": {
|
||||
"schema_version": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Key | Default | Effect |
|
||||
|-----|---------|--------|
|
||||
| `exchange.min_quote_volume` | `200000` | Minimum 24h quote volume for a symbol to appear in market snapshots |
|
||||
| `exchange.cache_ttl_seconds` | `3600` | How long the ccxt exchange instance (and `load_markets()` result) is cached |
|
||||
| `logging.schema_version` | `2` | Schema version stamped on every JSONL log entry |
|
||||
|
||||
---
|
||||
|
||||
## Runtime Model
|
||||
|
||||
Default data layout:
|
||||
Audit logs are written to:
|
||||
|
||||
```text
|
||||
~/.coinhunter/
|
||||
├── config.json
|
||||
├── positions.json
|
||||
├── accounts.json
|
||||
├── watchlist.json
|
||||
├── notes.json
|
||||
├── executions.json
|
||||
├── logs/
|
||||
├── reviews/
|
||||
├── cache/
|
||||
└── state/
|
||||
├── precheck_state.json
|
||||
└── external_gate.lock
|
||||
~/.coinhunter/logs/audit_YYYYMMDD.jsonl
|
||||
```
|
||||
|
||||
Credential resolution:
|
||||
Events include:
|
||||
|
||||
- Binance API keys are read from `~/.hermes/.env` by default.
|
||||
- Override with `COINHUNTER_ENV_FILE`.
|
||||
- Override home with `COINHUNTER_HOME` or `HERMES_HOME`.
|
||||
- `hermes` binary is resolved from `PATH`, then `~/.local/bin/hermes`, unless `HERMES_BIN` is set.
|
||||
- `trade_submitted`
|
||||
- `trade_filled`
|
||||
- `trade_failed`
|
||||
- `opportunity_portfolio_generated`
|
||||
- `opportunity_scan_generated`
|
||||
|
||||
---
|
||||
## Development
|
||||
|
||||
## Development Status
|
||||
|
||||
The codebase is actively maintained and refactored in small, safe steps.
|
||||
|
||||
**Recently completed:**
|
||||
- ✅ Unified CLI entrypoint with short aliases
|
||||
- ✅ Extracted `smart-executor` into `commands/` + `services/`
|
||||
- ✅ Extracted `precheck` into 9 focused service modules
|
||||
- ✅ Migrated all active command modules into `commands/`
|
||||
- ✅ Extracted `review_engine.py` core logic into `services/review_service.py`
|
||||
- ✅ Removed eager `PATHS` instantiation across services and commands
|
||||
- ✅ Fixed `smart_executor.py` lazy-loading facade
|
||||
- ✅ Standardized install to use `pip install -e .`
|
||||
- ✅ Made `external_gate` trigger_command configurable (no longer hardcodes hermes)
|
||||
- ✅ Removed dead `auto-trader` command
|
||||
- ✅ Backward-compatible root facades preserved
|
||||
|
||||
**Next priorities:**
|
||||
- 🔧 Add basic CI (lint + compileall + pytest)
|
||||
- 🔧 Unify output contract (JSON-first with `--pretty` option)
|
||||
|
||||
---
|
||||
|
||||
## Philosophy
|
||||
|
||||
CoinHunter is evolving toward:
|
||||
|
||||
- **Professional execution** — scientific position sizing, not moonshot gambling
|
||||
- **Maintainable architecture** — clear boundaries between CLI, services, and domain logic
|
||||
- **Safer operations** — dry-run, validation gates, and explicit decision logging
|
||||
- **Agent-friendly interfaces** — stable JSON outputs and predictable command contracts
|
||||
- **Less dependence on prompt-only correctness** — logic belongs in code, not just in system prompts
|
||||
|
||||
This repo is where that evolution happens.
|
||||
```bash
|
||||
pytest tests/ # run tests
|
||||
ruff check src tests # lint
|
||||
mypy src # type check
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user