clawquant 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- clawquant-0.1.0/LICENSE +21 -0
- clawquant-0.1.0/PKG-INFO +170 -0
- clawquant-0.1.0/README.md +140 -0
- clawquant-0.1.0/clawquant/__init__.py +1 -0
- clawquant-0.1.0/clawquant/clawquant_cli.py +303 -0
- clawquant-0.1.0/clawquant/cli/__init__.py +0 -0
- clawquant-0.1.0/clawquant/cli/backtest_cli.py +233 -0
- clawquant-0.1.0/clawquant/cli/data_cli.py +101 -0
- clawquant-0.1.0/clawquant/cli/deploy_cli.py +154 -0
- clawquant-0.1.0/clawquant/cli/radar_cli.py +98 -0
- clawquant-0.1.0/clawquant/cli/report_cli.py +80 -0
- clawquant-0.1.0/clawquant/cli/strategy_cli.py +215 -0
- clawquant-0.1.0/clawquant/core/__init__.py +0 -0
- clawquant-0.1.0/clawquant/core/backtest/__init__.py +0 -0
- clawquant-0.1.0/clawquant/core/backtest/batch.py +119 -0
- clawquant-0.1.0/clawquant/core/backtest/config.py +36 -0
- clawquant-0.1.0/clawquant/core/backtest/engine.py +346 -0
- clawquant-0.1.0/clawquant/core/backtest/events.py +58 -0
- clawquant-0.1.0/clawquant/core/backtest/execution.py +67 -0
- clawquant-0.1.0/clawquant/core/backtest/portfolio.py +170 -0
- clawquant-0.1.0/clawquant/core/backtest/result.py +69 -0
- clawquant-0.1.0/clawquant/core/backtest/risk.py +85 -0
- clawquant-0.1.0/clawquant/core/backtest/sweep.py +130 -0
- clawquant-0.1.0/clawquant/core/backtest/walkforward.py +169 -0
- clawquant-0.1.0/clawquant/core/data/__init__.py +0 -0
- clawquant-0.1.0/clawquant/core/data/alignment.py +91 -0
- clawquant-0.1.0/clawquant/core/data/cache.py +120 -0
- clawquant-0.1.0/clawquant/core/data/fetcher.py +150 -0
- clawquant-0.1.0/clawquant/core/data/inspector.py +119 -0
- clawquant-0.1.0/clawquant/core/data/models.py +59 -0
- clawquant-0.1.0/clawquant/core/deploy/__init__.py +0 -0
- clawquant-0.1.0/clawquant/core/deploy/manager.py +72 -0
- clawquant-0.1.0/clawquant/core/deploy/runner.py +196 -0
- clawquant-0.1.0/clawquant/core/evaluate/__init__.py +0 -0
- clawquant-0.1.0/clawquant/core/evaluate/metrics.py +154 -0
- clawquant-0.1.0/clawquant/core/evaluate/scorer.py +137 -0
- clawquant-0.1.0/clawquant/core/radar/__init__.py +0 -0
- clawquant-0.1.0/clawquant/core/radar/explainer.py +89 -0
- clawquant-0.1.0/clawquant/core/radar/scanner.py +150 -0
- clawquant-0.1.0/clawquant/core/report/__init__.py +0 -0
- clawquant-0.1.0/clawquant/core/report/charts.py +133 -0
- clawquant-0.1.0/clawquant/core/report/generator.py +155 -0
- clawquant-0.1.0/clawquant/core/report/json_report.py +40 -0
- clawquant-0.1.0/clawquant/core/report/markdown_report.py +127 -0
- clawquant-0.1.0/clawquant/core/runtime/__init__.py +0 -0
- clawquant-0.1.0/clawquant/core/runtime/base_strategy.py +116 -0
- clawquant-0.1.0/clawquant/core/runtime/loader.py +370 -0
- clawquant-0.1.0/clawquant/core/runtime/models.py +45 -0
- clawquant-0.1.0/clawquant/core/runtime/sandbox.py +88 -0
- clawquant-0.1.0/clawquant/core/utils/__init__.py +0 -0
- clawquant-0.1.0/clawquant/core/utils/logging.py +64 -0
- clawquant-0.1.0/clawquant/core/utils/output.py +104 -0
- clawquant-0.1.0/clawquant/core/utils/run_id.py +69 -0
- clawquant-0.1.0/clawquant/core/utils/state.py +12 -0
- clawquant-0.1.0/clawquant/integrations/__init__.py +0 -0
- clawquant-0.1.0/clawquant/integrations/binance_skill_wrapper/__init__.py +0 -0
- clawquant-0.1.0/clawquant/integrations/binance_skill_wrapper/wrapper.py +75 -0
- clawquant-0.1.0/clawquant/integrations/ccxt_fallback/__init__.py +0 -0
- clawquant-0.1.0/clawquant/integrations/ccxt_fallback/client.py +154 -0
- clawquant-0.1.0/clawquant/strategies_builtin/__init__.py +11 -0
- clawquant-0.1.0/clawquant/strategies_builtin/dca.py +149 -0
- clawquant-0.1.0/clawquant/strategies_builtin/grid.py +249 -0
- clawquant-0.1.0/clawquant/strategies_builtin/ma_crossover.py +202 -0
- clawquant-0.1.0/clawquant.egg-info/PKG-INFO +170 -0
- clawquant-0.1.0/clawquant.egg-info/SOURCES.txt +69 -0
- clawquant-0.1.0/clawquant.egg-info/dependency_links.txt +1 -0
- clawquant-0.1.0/clawquant.egg-info/entry_points.txt +2 -0
- clawquant-0.1.0/clawquant.egg-info/requires.txt +8 -0
- clawquant-0.1.0/clawquant.egg-info/top_level.txt +1 -0
- clawquant-0.1.0/pyproject.toml +45 -0
- clawquant-0.1.0/setup.cfg +4 -0
clawquant-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 duolaAmeng
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
clawquant-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: clawquant
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Quantitative trading research infrastructure for AI Agents
|
|
5
|
+
Author: duolaAmeng
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/duolaAmengweb3/clawquant-trader
|
|
8
|
+
Project-URL: Repository, https://github.com/duolaAmengweb3/clawquant-trader
|
|
9
|
+
Keywords: quantitative,trading,backtest,crypto,ccxt
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: typer>=0.9.0
|
|
22
|
+
Requires-Dist: ccxt>=4.0.0
|
|
23
|
+
Requires-Dist: pandas>=2.0.0
|
|
24
|
+
Requires-Dist: matplotlib>=3.7.0
|
|
25
|
+
Requires-Dist: pydantic>=2.0.0
|
|
26
|
+
Requires-Dist: rich>=13.0.0
|
|
27
|
+
Requires-Dist: pyarrow>=14.0.0
|
|
28
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# ClawQuant Trader
|
|
32
|
+
|
|
33
|
+
量化研究基建工具链,供 AI Agent(龙虾)通过自然语言调用,实现批量回测、策略评分、机会扫描、报告生成等研究能力。
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# 创建虚拟环境并安装依赖
|
|
39
|
+
uv venv .venv
|
|
40
|
+
source .venv/bin/activate
|
|
41
|
+
uv pip install -r requirements.txt
|
|
42
|
+
|
|
43
|
+
# 配置环境变量(可选,用于实盘数据)
|
|
44
|
+
cp .env.example .env
|
|
45
|
+
# 编辑 .env 填入 Binance API Key
|
|
46
|
+
|
|
47
|
+
# 查看帮助
|
|
48
|
+
python -m clawquant.clawquant_cli --help
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Commands
|
|
52
|
+
|
|
53
|
+
### Data Management
|
|
54
|
+
```bash
|
|
55
|
+
# 拉取数据
|
|
56
|
+
clawquant data pull BTC/USDT,ETH/USDT --interval 1h --days 10
|
|
57
|
+
|
|
58
|
+
# 数据质量检查
|
|
59
|
+
clawquant data inspect BTC/USDT --interval 1h
|
|
60
|
+
|
|
61
|
+
# 查看缓存状态
|
|
62
|
+
clawquant data cache-status
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Strategy Management
|
|
66
|
+
```bash
|
|
67
|
+
# 列出所有策略
|
|
68
|
+
clawquant strategy list
|
|
69
|
+
|
|
70
|
+
# 验证策略
|
|
71
|
+
clawquant strategy validate --name ma_crossover
|
|
72
|
+
|
|
73
|
+
# 生成策略模板
|
|
74
|
+
clawquant strategy scaffold --name my_strategy --output ./strategies_user/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Backtesting
|
|
78
|
+
```bash
|
|
79
|
+
# 单次回测
|
|
80
|
+
clawquant backtest run ma_crossover --symbol BTC/USDT --interval 1h --days 30
|
|
81
|
+
|
|
82
|
+
# 批量回测
|
|
83
|
+
clawquant backtest batch dca,ma_crossover,grid --symbols BTC/USDT,ETH/USDT
|
|
84
|
+
|
|
85
|
+
# 参数扫描
|
|
86
|
+
clawquant backtest sweep ma_crossover --grid '{"fast_period": [5,10,20], "slow_period": [20,30,50]}'
|
|
87
|
+
|
|
88
|
+
# 走前验证
|
|
89
|
+
clawquant backtest walkforward ma_crossover --days 90 --splits 3
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Radar (Opportunity Scanning)
|
|
93
|
+
```bash
|
|
94
|
+
# 扫描交易机会
|
|
95
|
+
clawquant radar scan --symbols BTC/USDT,ETH/USDT --strategies ma_crossover,dca
|
|
96
|
+
|
|
97
|
+
# 解释特定机会
|
|
98
|
+
clawquant radar explain BTC/USDT ma_crossover
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Reports
|
|
102
|
+
```bash
|
|
103
|
+
# 生成报告(JSON + Markdown + 图表)
|
|
104
|
+
clawquant report generate <run_id>
|
|
105
|
+
|
|
106
|
+
# 批量报告对比
|
|
107
|
+
clawquant report batch <run_id1>,<run_id2>,<run_id3>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Deployment
|
|
111
|
+
```bash
|
|
112
|
+
# 模拟交易
|
|
113
|
+
clawquant deploy paper ma_crossover --symbol BTC/USDT
|
|
114
|
+
|
|
115
|
+
# 实盘交易(需要确认)
|
|
116
|
+
clawquant deploy live ma_crossover --i-know-what-im-doing
|
|
117
|
+
|
|
118
|
+
# 查看部署状态
|
|
119
|
+
clawquant deploy status
|
|
120
|
+
|
|
121
|
+
# 停止/平仓
|
|
122
|
+
clawquant deploy stop ma_crossover
|
|
123
|
+
clawquant deploy flatten ma_crossover
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## JSON Output
|
|
127
|
+
|
|
128
|
+
所有命令支持 `--json` 全局标志,输出 JSON 格式供 Agent 消费:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
clawquant --json backtest run ma_crossover --symbol BTC/USDT --days 10
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Built-in Strategies
|
|
135
|
+
|
|
136
|
+
| Strategy | Description | Type |
|
|
137
|
+
|----------|-------------|------|
|
|
138
|
+
| `dca` | Dollar Cost Averaging - 定投 | Passive |
|
|
139
|
+
| `ma_crossover` | Moving Average Crossover - 均线交叉 | Trend Following |
|
|
140
|
+
| `grid` | Grid Trading - 网格交易 | Mean Reversion |
|
|
141
|
+
|
|
142
|
+
## Custom Strategies
|
|
143
|
+
|
|
144
|
+
将自定义策略 `.py` 文件放入 `strategies_user/` 目录,继承 `BaseStrategy` 并实现 6 个方法即可被自动发现。
|
|
145
|
+
|
|
146
|
+
使用 `clawquant strategy scaffold` 生成模板。
|
|
147
|
+
|
|
148
|
+
## Project Structure
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
clawquant/
|
|
152
|
+
├── clawquant_cli.py # CLI 入口
|
|
153
|
+
├── cli/ # CLI 命令实现
|
|
154
|
+
├── core/ # 核心逻辑
|
|
155
|
+
│ ├── data/ # 数据拉取/缓存/检查
|
|
156
|
+
│ ├── runtime/ # 策略加载/沙箱
|
|
157
|
+
│ ├── backtest/ # 回测引擎
|
|
158
|
+
│ ├── evaluate/ # 指标计算/评分
|
|
159
|
+
│ ├── radar/ # 机会扫描
|
|
160
|
+
│ ├── report/ # 报告生成
|
|
161
|
+
│ └── deploy/ # 部署管理
|
|
162
|
+
├── strategies_builtin/ # 内置策略
|
|
163
|
+
├── strategies_user/ # 用户策略
|
|
164
|
+
├── integrations/ # 外部服务集成
|
|
165
|
+
└── skills/ # Agent Skill 定义
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Tech Stack
|
|
169
|
+
|
|
170
|
+
- **Python 3.11+** | **Typer** (CLI) | **ccxt** (Exchange) | **pandas** (Data) | **matplotlib** (Charts) | **pydantic** (Models) | **Rich** (Output)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# ClawQuant Trader
|
|
2
|
+
|
|
3
|
+
量化研究基建工具链,供 AI Agent(龙虾)通过自然语言调用,实现批量回测、策略评分、机会扫描、报告生成等研究能力。
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 创建虚拟环境并安装依赖
|
|
9
|
+
uv venv .venv
|
|
10
|
+
source .venv/bin/activate
|
|
11
|
+
uv pip install -r requirements.txt
|
|
12
|
+
|
|
13
|
+
# 配置环境变量(可选,用于实盘数据)
|
|
14
|
+
cp .env.example .env
|
|
15
|
+
# 编辑 .env 填入 Binance API Key
|
|
16
|
+
|
|
17
|
+
# 查看帮助
|
|
18
|
+
python -m clawquant.clawquant_cli --help
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Commands
|
|
22
|
+
|
|
23
|
+
### Data Management
|
|
24
|
+
```bash
|
|
25
|
+
# 拉取数据
|
|
26
|
+
clawquant data pull BTC/USDT,ETH/USDT --interval 1h --days 10
|
|
27
|
+
|
|
28
|
+
# 数据质量检查
|
|
29
|
+
clawquant data inspect BTC/USDT --interval 1h
|
|
30
|
+
|
|
31
|
+
# 查看缓存状态
|
|
32
|
+
clawquant data cache-status
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Strategy Management
|
|
36
|
+
```bash
|
|
37
|
+
# 列出所有策略
|
|
38
|
+
clawquant strategy list
|
|
39
|
+
|
|
40
|
+
# 验证策略
|
|
41
|
+
clawquant strategy validate --name ma_crossover
|
|
42
|
+
|
|
43
|
+
# 生成策略模板
|
|
44
|
+
clawquant strategy scaffold --name my_strategy --output ./strategies_user/
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Backtesting
|
|
48
|
+
```bash
|
|
49
|
+
# 单次回测
|
|
50
|
+
clawquant backtest run ma_crossover --symbol BTC/USDT --interval 1h --days 30
|
|
51
|
+
|
|
52
|
+
# 批量回测
|
|
53
|
+
clawquant backtest batch dca,ma_crossover,grid --symbols BTC/USDT,ETH/USDT
|
|
54
|
+
|
|
55
|
+
# 参数扫描
|
|
56
|
+
clawquant backtest sweep ma_crossover --grid '{"fast_period": [5,10,20], "slow_period": [20,30,50]}'
|
|
57
|
+
|
|
58
|
+
# 走前验证
|
|
59
|
+
clawquant backtest walkforward ma_crossover --days 90 --splits 3
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Radar (Opportunity Scanning)
|
|
63
|
+
```bash
|
|
64
|
+
# 扫描交易机会
|
|
65
|
+
clawquant radar scan --symbols BTC/USDT,ETH/USDT --strategies ma_crossover,dca
|
|
66
|
+
|
|
67
|
+
# 解释特定机会
|
|
68
|
+
clawquant radar explain BTC/USDT ma_crossover
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Reports
|
|
72
|
+
```bash
|
|
73
|
+
# 生成报告(JSON + Markdown + 图表)
|
|
74
|
+
clawquant report generate <run_id>
|
|
75
|
+
|
|
76
|
+
# 批量报告对比
|
|
77
|
+
clawquant report batch <run_id1>,<run_id2>,<run_id3>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Deployment
|
|
81
|
+
```bash
|
|
82
|
+
# 模拟交易
|
|
83
|
+
clawquant deploy paper ma_crossover --symbol BTC/USDT
|
|
84
|
+
|
|
85
|
+
# 实盘交易(需要确认)
|
|
86
|
+
clawquant deploy live ma_crossover --i-know-what-im-doing
|
|
87
|
+
|
|
88
|
+
# 查看部署状态
|
|
89
|
+
clawquant deploy status
|
|
90
|
+
|
|
91
|
+
# 停止/平仓
|
|
92
|
+
clawquant deploy stop ma_crossover
|
|
93
|
+
clawquant deploy flatten ma_crossover
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## JSON Output
|
|
97
|
+
|
|
98
|
+
所有命令支持 `--json` 全局标志,输出 JSON 格式供 Agent 消费:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
clawquant --json backtest run ma_crossover --symbol BTC/USDT --days 10
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Built-in Strategies
|
|
105
|
+
|
|
106
|
+
| Strategy | Description | Type |
|
|
107
|
+
|----------|-------------|------|
|
|
108
|
+
| `dca` | Dollar Cost Averaging - 定投 | Passive |
|
|
109
|
+
| `ma_crossover` | Moving Average Crossover - 均线交叉 | Trend Following |
|
|
110
|
+
| `grid` | Grid Trading - 网格交易 | Mean Reversion |
|
|
111
|
+
|
|
112
|
+
## Custom Strategies
|
|
113
|
+
|
|
114
|
+
将自定义策略 `.py` 文件放入 `strategies_user/` 目录,继承 `BaseStrategy` 并实现 6 个方法即可被自动发现。
|
|
115
|
+
|
|
116
|
+
使用 `clawquant strategy scaffold` 生成模板。
|
|
117
|
+
|
|
118
|
+
## Project Structure
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
clawquant/
|
|
122
|
+
├── clawquant_cli.py # CLI 入口
|
|
123
|
+
├── cli/ # CLI 命令实现
|
|
124
|
+
├── core/ # 核心逻辑
|
|
125
|
+
│ ├── data/ # 数据拉取/缓存/检查
|
|
126
|
+
│ ├── runtime/ # 策略加载/沙箱
|
|
127
|
+
│ ├── backtest/ # 回测引擎
|
|
128
|
+
│ ├── evaluate/ # 指标计算/评分
|
|
129
|
+
│ ├── radar/ # 机会扫描
|
|
130
|
+
│ ├── report/ # 报告生成
|
|
131
|
+
│ └── deploy/ # 部署管理
|
|
132
|
+
├── strategies_builtin/ # 内置策略
|
|
133
|
+
├── strategies_user/ # 用户策略
|
|
134
|
+
├── integrations/ # 外部服务集成
|
|
135
|
+
└── skills/ # Agent Skill 定义
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Tech Stack
|
|
139
|
+
|
|
140
|
+
- **Python 3.11+** | **Typer** (CLI) | **ccxt** (Exchange) | **pandas** (Data) | **matplotlib** (Charts) | **pydantic** (Models) | **Rich** (Output)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"""ClawQuant Trader - CLI entry point.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
python -m clawquant.clawquant_cli --help
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from clawquant import __version__
|
|
12
|
+
|
|
13
|
+
# ---------------------------------------------------------------------------
|
|
14
|
+
# Main app
|
|
15
|
+
# ---------------------------------------------------------------------------
|
|
16
|
+
app = typer.Typer(
|
|
17
|
+
name="clawquant",
|
|
18
|
+
help="ClawQuant Trader - Quantitative Research Infrastructure",
|
|
19
|
+
add_completion=False,
|
|
20
|
+
no_args_is_help=True,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# ---------------------------------------------------------------------------
|
|
24
|
+
# Global state (stored in shared module to survive python -m re-import)
|
|
25
|
+
# ---------------------------------------------------------------------------
|
|
26
|
+
from clawquant.core.utils.state import get_json_mode as _get_json_mode, set_json_mode
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _version_callback(value: bool) -> None:
|
|
30
|
+
if value:
|
|
31
|
+
typer.echo(f"ClawQuant Trader v{__version__}")
|
|
32
|
+
raise typer.Exit()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@app.callback()
|
|
36
|
+
def main(
|
|
37
|
+
version: Optional[bool] = typer.Option(
|
|
38
|
+
None, "--version", "-V", help="Show version and exit.",
|
|
39
|
+
callback=_version_callback, is_eager=True,
|
|
40
|
+
),
|
|
41
|
+
json_output: bool = typer.Option(
|
|
42
|
+
False, "--json", help="Output results as JSON instead of Rich tables.",
|
|
43
|
+
),
|
|
44
|
+
) -> None:
|
|
45
|
+
"""ClawQuant Trader - Quantitative Research Infrastructure."""
|
|
46
|
+
set_json_mode(json_output)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ---------------------------------------------------------------------------
|
|
50
|
+
# Sub-app: data
|
|
51
|
+
# ---------------------------------------------------------------------------
|
|
52
|
+
data_app = typer.Typer(help="Data management commands", no_args_is_help=True)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@data_app.command("pull")
|
|
56
|
+
def data_pull(
|
|
57
|
+
symbols: str = typer.Argument(..., help="Comma-separated symbols, e.g. BTC/USDT,ETH/USDT"),
|
|
58
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
59
|
+
days: int = typer.Option(10, "--days", "-d", help="Number of days to fetch"),
|
|
60
|
+
exchange: str = typer.Option("binance", "--exchange", "-e", help="Exchange name"),
|
|
61
|
+
) -> None:
|
|
62
|
+
"""Pull OHLCV data for one or more symbols."""
|
|
63
|
+
from clawquant.cli.data_cli import pull
|
|
64
|
+
pull(symbols=symbols, interval=interval, days=days, exchange=exchange, json_mode=_get_json_mode())
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@data_app.command("inspect")
|
|
68
|
+
def data_inspect(
|
|
69
|
+
symbol: str = typer.Argument(..., help="Symbol to check, e.g. BTC/USDT"),
|
|
70
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
71
|
+
) -> None:
|
|
72
|
+
"""Run data quality checks on a cached dataset."""
|
|
73
|
+
from clawquant.cli.data_cli import inspect
|
|
74
|
+
inspect(symbol=symbol, interval=interval, json_mode=_get_json_mode())
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@data_app.command("cache-status")
|
|
78
|
+
def data_cache_status() -> None:
|
|
79
|
+
"""Show all cached data files."""
|
|
80
|
+
from clawquant.cli.data_cli import cache_status
|
|
81
|
+
cache_status(json_mode=_get_json_mode())
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
app.add_typer(data_app, name="data")
|
|
85
|
+
|
|
86
|
+
# ---------------------------------------------------------------------------
|
|
87
|
+
# Sub-app: strategy (delegated)
|
|
88
|
+
# ---------------------------------------------------------------------------
|
|
89
|
+
from clawquant.cli.strategy_cli import strategy_app # noqa: E402
|
|
90
|
+
|
|
91
|
+
app.add_typer(strategy_app, name="strategy")
|
|
92
|
+
|
|
93
|
+
# ---------------------------------------------------------------------------
|
|
94
|
+
# Sub-app: backtest
|
|
95
|
+
# ---------------------------------------------------------------------------
|
|
96
|
+
backtest_app = typer.Typer(help="Backtesting commands", no_args_is_help=True)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@backtest_app.command("run")
|
|
100
|
+
def backtest_run(
|
|
101
|
+
strategy: str = typer.Argument(..., help="Strategy name"),
|
|
102
|
+
symbol: str = typer.Option("BTC/USDT", "--symbol", "-s", help="Trading pair"),
|
|
103
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
104
|
+
days: int = typer.Option(30, "--days", "-d", help="Backtest window in days"),
|
|
105
|
+
capital: float = typer.Option(10000.0, "--capital", "-c", help="Initial capital in USDT"),
|
|
106
|
+
fee_bps: int = typer.Option(10, "--fee-bps", help="Fee in basis points"),
|
|
107
|
+
slippage_bps: int = typer.Option(5, "--slippage-bps", help="Slippage in basis points"),
|
|
108
|
+
params: Optional[str] = typer.Option(None, "--params", "-p", help='Strategy params JSON, e.g. \'{"fast_period": 10}\''),
|
|
109
|
+
dry_run: bool = typer.Option(False, "--dry-run", help="Check readiness without running"),
|
|
110
|
+
) -> None:
|
|
111
|
+
"""Run a single backtest."""
|
|
112
|
+
from clawquant.cli.backtest_cli import run
|
|
113
|
+
run(strategy=strategy, symbol=symbol, interval=interval, days=days,
|
|
114
|
+
capital=capital, fee_bps=fee_bps, slippage_bps=slippage_bps,
|
|
115
|
+
params=params, dry_run=dry_run, json_mode=_get_json_mode())
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@backtest_app.command("batch")
|
|
119
|
+
def backtest_batch(
|
|
120
|
+
strategies: str = typer.Argument(..., help="Comma-separated strategy names"),
|
|
121
|
+
symbols: str = typer.Option("BTC/USDT", "--symbols", "-s", help="Comma-separated symbols"),
|
|
122
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
123
|
+
days: int = typer.Option(30, "--days", "-d", help="Backtest window in days"),
|
|
124
|
+
capital: float = typer.Option(10000.0, "--capital", "-c", help="Initial capital"),
|
|
125
|
+
) -> None:
|
|
126
|
+
"""Run batch backtests across strategies and symbols."""
|
|
127
|
+
from clawquant.cli.backtest_cli import batch
|
|
128
|
+
batch(strategies=strategies, symbols=symbols, interval=interval, days=days,
|
|
129
|
+
capital=capital, json_mode=_get_json_mode())
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@backtest_app.command("sweep")
|
|
133
|
+
def backtest_sweep(
|
|
134
|
+
strategy: str = typer.Argument(..., help="Strategy name"),
|
|
135
|
+
symbol: str = typer.Option("BTC/USDT", "--symbol", "-s", help="Trading pair"),
|
|
136
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
137
|
+
days: int = typer.Option(30, "--days", "-d", help="Backtest window"),
|
|
138
|
+
param_grid: Optional[str] = typer.Option(None, "--grid", "-g", help='Param grid JSON, e.g. \'{"fast_period": [5,10,20]}\''),
|
|
139
|
+
mode: str = typer.Option("grid", "--mode", "-m", help="Sweep mode: grid or random"),
|
|
140
|
+
n_random: int = typer.Option(20, "--n-random", help="Number of random samples"),
|
|
141
|
+
) -> None:
|
|
142
|
+
"""Run parameter sweep over a strategy."""
|
|
143
|
+
from clawquant.cli.backtest_cli import sweep
|
|
144
|
+
sweep(strategy=strategy, symbol=symbol, interval=interval, days=days,
|
|
145
|
+
param_grid=param_grid, mode=mode, n_random=n_random, json_mode=_get_json_mode())
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@backtest_app.command("walkforward")
|
|
149
|
+
def backtest_walkforward(
|
|
150
|
+
strategy: str = typer.Argument(..., help="Strategy name"),
|
|
151
|
+
symbol: str = typer.Option("BTC/USDT", "--symbol", "-s", help="Trading pair"),
|
|
152
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
153
|
+
days: int = typer.Option(90, "--days", "-d", help="Total data window"),
|
|
154
|
+
train_pct: float = typer.Option(0.7, "--train-pct", help="Training fraction"),
|
|
155
|
+
n_splits: int = typer.Option(3, "--splits", "-n", help="Number of rolling splits"),
|
|
156
|
+
param_grid: Optional[str] = typer.Option(None, "--grid", "-g", help="Param grid JSON"),
|
|
157
|
+
) -> None:
|
|
158
|
+
"""Run walk-forward validation."""
|
|
159
|
+
from clawquant.cli.backtest_cli import walkforward
|
|
160
|
+
walkforward(strategy=strategy, symbol=symbol, interval=interval, days=days,
|
|
161
|
+
train_pct=train_pct, n_splits=n_splits, param_grid=param_grid,
|
|
162
|
+
json_mode=_get_json_mode())
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
app.add_typer(backtest_app, name="backtest")
|
|
166
|
+
|
|
167
|
+
# ---------------------------------------------------------------------------
|
|
168
|
+
# Sub-app: radar
|
|
169
|
+
# ---------------------------------------------------------------------------
|
|
170
|
+
radar_app = typer.Typer(help="Opportunity scanning commands", no_args_is_help=True)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@radar_app.command("scan")
|
|
174
|
+
def radar_scan(
|
|
175
|
+
symbols: str = typer.Option("BTC/USDT,ETH/USDT", "--symbols", "-s", help="Comma-separated symbols"),
|
|
176
|
+
strategies: str = typer.Option("ma_crossover,dca", "--strategies", help="Comma-separated strategies"),
|
|
177
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
178
|
+
days: int = typer.Option(10, "--days", "-d", help="Data window"),
|
|
179
|
+
exchange: str = typer.Option("binance", "--exchange", "-e", help="Exchange"),
|
|
180
|
+
top_n: int = typer.Option(10, "--top", "-n", help="Top N results"),
|
|
181
|
+
) -> None:
|
|
182
|
+
"""Scan for trading opportunities."""
|
|
183
|
+
from clawquant.cli.radar_cli import scan
|
|
184
|
+
scan(symbols=symbols, strategies=strategies, interval=interval, days=days,
|
|
185
|
+
exchange=exchange, top_n=top_n, json_mode=_get_json_mode())
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@radar_app.command("explain")
|
|
189
|
+
def radar_explain(
|
|
190
|
+
symbol: str = typer.Argument(..., help="Symbol to explain"),
|
|
191
|
+
strategy: str = typer.Argument(..., help="Strategy name"),
|
|
192
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
193
|
+
days: int = typer.Option(10, "--days", "-d", help="Data window"),
|
|
194
|
+
) -> None:
|
|
195
|
+
"""Explain a specific opportunity."""
|
|
196
|
+
from clawquant.cli.radar_cli import explain
|
|
197
|
+
explain(symbol=symbol, strategy=strategy, interval=interval, days=days,
|
|
198
|
+
json_mode=_get_json_mode())
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
app.add_typer(radar_app, name="radar")
|
|
202
|
+
|
|
203
|
+
# ---------------------------------------------------------------------------
|
|
204
|
+
# Sub-app: report
|
|
205
|
+
# ---------------------------------------------------------------------------
|
|
206
|
+
report_app = typer.Typer(help="Report generation commands", no_args_is_help=True)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
@report_app.command("generate")
|
|
210
|
+
def report_generate(
|
|
211
|
+
run_id: str = typer.Argument(..., help="Run ID to generate report for"),
|
|
212
|
+
formats: Optional[str] = typer.Option(None, "--formats", "-f", help="Comma-separated: json,md,charts"),
|
|
213
|
+
) -> None:
|
|
214
|
+
"""Generate reports for a backtest run."""
|
|
215
|
+
from clawquant.cli.report_cli import generate
|
|
216
|
+
generate(run_id=run_id, formats=formats, json_mode=_get_json_mode())
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
@report_app.command("batch")
|
|
220
|
+
def report_batch(
|
|
221
|
+
run_ids: str = typer.Argument(..., help="Comma-separated run IDs"),
|
|
222
|
+
) -> None:
|
|
223
|
+
"""Generate and compare reports for multiple runs."""
|
|
224
|
+
from clawquant.cli.report_cli import batch_generate
|
|
225
|
+
batch_generate(run_ids=run_ids, json_mode=_get_json_mode())
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
app.add_typer(report_app, name="report")
|
|
229
|
+
|
|
230
|
+
# ---------------------------------------------------------------------------
|
|
231
|
+
# Sub-app: deploy
|
|
232
|
+
# ---------------------------------------------------------------------------
|
|
233
|
+
deploy_app = typer.Typer(help="Deployment commands", no_args_is_help=True)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
@deploy_app.command("paper")
|
|
237
|
+
def deploy_paper(
|
|
238
|
+
strategy: str = typer.Argument(..., help="Strategy name"),
|
|
239
|
+
symbol: str = typer.Option("BTC/USDT", "--symbol", "-s", help="Trading pair"),
|
|
240
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
241
|
+
capital: float = typer.Option(10000.0, "--capital", "-c", help="Initial capital"),
|
|
242
|
+
params: Optional[str] = typer.Option(None, "--params", "-p", help="Strategy params JSON"),
|
|
243
|
+
exchange: str = typer.Option("binance", "--exchange", "-e", help="Exchange"),
|
|
244
|
+
) -> None:
|
|
245
|
+
"""Start paper trading."""
|
|
246
|
+
from clawquant.cli.deploy_cli import paper
|
|
247
|
+
paper(strategy=strategy, symbol=symbol, interval=interval, capital=capital,
|
|
248
|
+
params=params, exchange=exchange, json_mode=_get_json_mode())
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@deploy_app.command("live")
|
|
252
|
+
def deploy_live(
|
|
253
|
+
strategy: str = typer.Argument(..., help="Strategy name"),
|
|
254
|
+
symbol: str = typer.Option("BTC/USDT", "--symbol", "-s", help="Trading pair"),
|
|
255
|
+
interval: str = typer.Option("1h", "--interval", "-i", help="Bar interval"),
|
|
256
|
+
capital: float = typer.Option(10000.0, "--capital", "-c", help="Initial capital"),
|
|
257
|
+
params: Optional[str] = typer.Option(None, "--params", "-p", help="Strategy params JSON"),
|
|
258
|
+
exchange: str = typer.Option("binance", "--exchange", "-e", help="Exchange"),
|
|
259
|
+
i_know_what_im_doing: bool = typer.Option(False, "--i-know-what-im-doing", help="Confirm live trading risks"),
|
|
260
|
+
) -> None:
|
|
261
|
+
"""Start live trading (requires --i-know-what-im-doing)."""
|
|
262
|
+
from clawquant.cli.deploy_cli import live
|
|
263
|
+
live(strategy=strategy, symbol=symbol, interval=interval, capital=capital,
|
|
264
|
+
params=params, exchange=exchange, confirm=i_know_what_im_doing,
|
|
265
|
+
json_mode=_get_json_mode())
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@deploy_app.command("status")
|
|
269
|
+
def deploy_status() -> None:
|
|
270
|
+
"""Show deployment statuses."""
|
|
271
|
+
from clawquant.cli.deploy_cli import status
|
|
272
|
+
status(json_mode=_get_json_mode())
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
@deploy_app.command("stop")
|
|
276
|
+
def deploy_stop(
|
|
277
|
+
strategy: str = typer.Argument(..., help="Strategy name"),
|
|
278
|
+
symbol: str = typer.Option("BTC/USDT", "--symbol", "-s", help="Trading pair"),
|
|
279
|
+
mode: str = typer.Option("paper", "--mode", "-m", help="paper or live"),
|
|
280
|
+
) -> None:
|
|
281
|
+
"""Stop a deployment."""
|
|
282
|
+
from clawquant.cli.deploy_cli import stop
|
|
283
|
+
stop(strategy=strategy, symbol=symbol, mode=mode, json_mode=_get_json_mode())
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@deploy_app.command("flatten")
|
|
287
|
+
def deploy_flatten(
|
|
288
|
+
strategy: str = typer.Argument(..., help="Strategy name"),
|
|
289
|
+
symbol: str = typer.Option("BTC/USDT", "--symbol", "-s", help="Trading pair"),
|
|
290
|
+
mode: str = typer.Option("paper", "--mode", "-m", help="paper or live"),
|
|
291
|
+
) -> None:
|
|
292
|
+
"""Flatten positions and stop a deployment."""
|
|
293
|
+
from clawquant.cli.deploy_cli import flatten
|
|
294
|
+
flatten(strategy=strategy, symbol=symbol, mode=mode, json_mode=_get_json_mode())
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
app.add_typer(deploy_app, name="deploy")
|
|
298
|
+
|
|
299
|
+
# ---------------------------------------------------------------------------
|
|
300
|
+
# Module entry-point
|
|
301
|
+
# ---------------------------------------------------------------------------
|
|
302
|
+
if __name__ == "__main__":
|
|
303
|
+
app()
|
|
File without changes
|