@openfinclaw/openfinclaw-strategy 0.0.11

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.
@@ -0,0 +1,165 @@
1
+ # Strategy Fork Skill
2
+
3
+ 从 Hub 下载公开策略到本地,支持二次开发和优化。
4
+
5
+ ## 概述
6
+
7
+ 本 skill 提供从 hub.openfinclaw.ai 下载策略的功能,使用户能够:
8
+
9
+ - 浏览并下载公开策略到本地
10
+ - 基于现有策略进行修改和优化
11
+ - 发布自己的改进版本
12
+
13
+ ## 工具列表
14
+
15
+ | 工具 | 用途 |
16
+ | ------------------ | --------------------- |
17
+ | `skill_fork` | 从 Hub 下载策略到本地 |
18
+ | `skill_list_local` | 列出本地已下载的策略 |
19
+ | `skill_get_info` | 获取 Hub 策略详情 |
20
+
21
+ ## 目录结构
22
+
23
+ ```
24
+ ~/.openfinclaw/workspace/strategies/
25
+ └── 2026-03-16/ # 按日期组织
26
+ ├── btc-adaptive-dca-34a5792f/ # 名称 + 短ID(防冲突)
27
+ │ ├── fep.yaml # 策略配置
28
+ │ ├── scripts/
29
+ │ │ └── strategy.py # 策略代码
30
+ │ └── .fork-meta.json # 元数据
31
+ └── my-new-strategy/ # 自建策略(无短ID)
32
+ └── ...
33
+ ```
34
+
35
+ ## 使用方式
36
+
37
+ ### 1. 查看策略信息
38
+
39
+ 在 fork 之前,可以先获取策略详情:
40
+
41
+ ```
42
+ 调用 skill_get_info 并传入策略 ID
43
+ ```
44
+
45
+ 示例参数:
46
+
47
+ ```json
48
+ {
49
+ "strategyId": "34a5792f-7d20-4a15-90f3-26f1c54fa4a6"
50
+ }
51
+ ```
52
+
53
+ 也支持 Hub URL:
54
+
55
+ - URL: `https://hub.openfinclaw.ai/strategy/34a5792f-7d20-4a15-90f3-26f1c54fa4a6`
56
+
57
+ ### 2. Fork 策略
58
+
59
+ 下载策略到本地:
60
+
61
+ ```
62
+ 调用 skill_fork 并传入策略 ID
63
+ ```
64
+
65
+ 示例参数:
66
+
67
+ ```json
68
+ {
69
+ "strategyId": "34a5792f-7d20-4a15-90f3-26f1c54fa4a6"
70
+ }
71
+ ```
72
+
73
+ 可选参数:
74
+
75
+ - `targetDir`: 自定义目标目录
76
+ - `dateDir`: 指定日期目录(YYYY-MM-DD)
77
+
78
+ ### 3. 列出本地策略
79
+
80
+ 查看已下载的策略:
81
+
82
+ ```
83
+ 调用 skill_list_local
84
+ ```
85
+
86
+ ### 4. 编辑和发布
87
+
88
+ fork 后的完整流程:
89
+
90
+ 1. 编辑 `scripts/strategy.py` 修改策略逻辑
91
+ 2. 调用 `skill_validate` 验证策略包
92
+ 3. 调用 `skill_publish` 发布新版本
93
+
94
+ ## CLI 命令
95
+
96
+ 用户也可以通过命令行操作:
97
+
98
+ ```bash
99
+ # Fork 策略
100
+ openfinclaw strategy fork 34a5792f-7d20-4a15-90f3-26f1c54fa4a6
101
+
102
+ # 列出本地策略
103
+ openfinclaw strategy list
104
+
105
+ # 查看详情
106
+ openfinclaw strategy show btc-adaptive-dca-34a5792f --remote
107
+
108
+ # 删除策略
109
+ openfinclaw strategy remove btc-adaptive-dca-34a5792f --force
110
+ ```
111
+
112
+ ## 典型场景
113
+
114
+ ### 场景 1:学习优秀策略
115
+
116
+ 用户: "帮我下载那个收益 453% 的 BTC 策略"
117
+
118
+ Agent:
119
+
120
+ 1. 搜索 Hub 或访问 leaderboard 找到策略 ID
121
+ 2. 调用 `skill_get_info` 展示策略信息
122
+ 3. 用户确认后调用 `skill_fork` 下载
123
+ 4. 返回本地路径供用户研究
124
+
125
+ ### 场景 2:基于现有策略优化
126
+
127
+ 用户: "我想在 BTC DCA 策略基础上增加止损功能"
128
+
129
+ Agent:
130
+
131
+ 1. 调用 `skill_fork` 下载原策略
132
+ 2. 读取 `scripts/strategy.py` 分析逻辑
133
+ 3. 添加止损参数和逻辑
134
+ 4. 调用 `skill_validate` 验证
135
+ 5. 建议用户发布新版本
136
+
137
+ ### 场景 3:管理本地策略
138
+
139
+ 用户: "我之前下载了哪些策略?"
140
+
141
+ Agent:
142
+
143
+ 1. 调用 `skill_list_local` 列出所有本地策略
144
+ 2. 按日期分组展示
145
+ 3. 可进一步调用 `skill_get_info` 获取特定策略的最新信息
146
+
147
+ ## 注意事项
148
+
149
+ 1. **API Key**: 某些操作需要配置 API Key
150
+
151
+ ```bash
152
+ openfinclaw config set plugins.entries.openfinclaw.config.skillApiKey YOUR_KEY
153
+ ```
154
+
155
+ 2. **同名冲突**: 如果两个策略名称相同,会自动添加短 ID 后缀区分
156
+
157
+ 3. **目录已存在**: 如果目标目录已存在,fork 会失败并提示路径冲突
158
+
159
+ 4. **网络要求**: 需要能够访问 hub.openfinclaw.ai
160
+
161
+ ## 相关文档
162
+
163
+ - [策略 Fork 模块设计文档](/finance/strategy-fork-module-design)
164
+ - [FEP v2.0 协议说明](/finance/FEP-v2.0-协议说明)
165
+ - [策略发布指南](/skills/skill-publish/SKILL.md)
@@ -0,0 +1,285 @@
1
+ ---
2
+ name: strategy-pack
3
+ description: "Create and validate Findoo Backtest (FEP v2.0) strategy packages. Use when the user wants to create a strategy pack, generate fep.yaml and strategy.py, or prepare a folder for remote backtest. Always validate with backtest_remote_validate before zipping and submitting."
4
+ metadata: { "openclaw": { "requires": { "extensions": ["fin-backtest-remote"] } } }
5
+ ---
6
+
7
+ # 策略包生成与校验 (FEP v2.0)
8
+
9
+ 当用户要**创建策略包**、**生成回测策略包**、**写 fep 策略**、**打包后提交回测**时,按以下结构生成目录和文件,并在**上传前必须用 `backtest_remote_validate` 校验**,通过后再打包为 ZIP 并提交。
10
+
11
+ ## 何时触发
12
+
13
+ - 用户说:创建策略包、生成策略包、写一个 fep 策略、帮我打包成回测包、准备提交回测
14
+ - 用户要:按回测服务器要求生成目录结构、写 fep.yaml 和 strategy.py
15
+
16
+ ## 策略包目录结构(必选 + 可选)
17
+
18
+ ```
19
+ <strategy-dir>/
20
+ ├── fep.yaml # 必需:策略元数据与回测配置
21
+ └── scripts/
22
+ └── strategy.py # 必需:策略入口,必须实现 compute(data) 或 select(universe)
23
+ ├── risk_manager.py # 可选
24
+ └── indicators.py # 可选
25
+ └── data/ # 可选:自定义数据
26
+ ```
27
+
28
+ ## fep.yaml 配置 (FEP v2.0)
29
+
30
+ ### 最小配置 (L1 Script)
31
+
32
+ ```yaml
33
+ fep: "2.0"
34
+
35
+ # ── 身份标识 (必填) ───────────────────────────────────────
36
+ identity:
37
+ id: fin-dca-basic-test # 必填:策略唯一标识(英文 + 连字符)
38
+ type: strategy # strategy | indicator | connector(默认 strategy)
39
+ name: "DCA Basic Test Strategy" # 必填:策略显示名称
40
+ version: "1.0.0" # 必填:语义化版本号
41
+ style: dca # 必填:trend | mean-reversion | momentum | value | growth | breakout | rotation | hybrid
42
+ visibility: public # 必填:public | private | unlisted
43
+ summary: "Simple DCA strategy for BTC" # 必填:一句话策略描述
44
+ description: "A simple DCA strategy that buys BTC periodically" # 必填:详细策略描述
45
+ license: MIT # 必填:MIT | CC-BY-4.0 | proprietary
46
+ tags: [dca, btc, crypto] # 必填:标签数组
47
+ author:
48
+ name: "OpenFinClaw" # 必填:作者名
49
+ wallet: "0x..." # 可选:收益分配地址
50
+ changelog:
51
+ - version: "1.0.0"
52
+ date: "2025-01-01"
53
+ changes: "Initial release"
54
+
55
+ # ── 技术配置 (可选,有默认值) ───────────────────────────────
56
+ technical:
57
+ language: python # 默认 python
58
+ entryPoint: strategy.py # 默认 strategy.py
59
+
60
+ # ── 策略参数 (可选) ───────────────────────────────────────
61
+ parameters:
62
+ - name: base_amount
63
+ default: 100
64
+ type: number
65
+ label: "基础定投金额"
66
+ range: { min: 10, max: 10000 }
67
+
68
+ # ── 回测配置 (必填) ───────────────────────────────────────
69
+ backtest:
70
+ symbol: "BTC/USDT" # 必填:交易品种(服务端自动推断市场、货币、手续费)
71
+ timeframe: 1d # 可选:1m | 5m | 15m | 30m | 1h | 4h | 1d | 1w(默认 1d)
72
+ defaultPeriod:
73
+ startDate: "2024-01-01"
74
+ endDate: "2024-12-31"
75
+ initialCapital: 10000 # 必填:初始资金
76
+
77
+ # ── 风控配置 (可选) ───────────────────────────────────────
78
+ risk:
79
+ maxDrawdownThreshold: 25 # 最大回撤限制 (%),默认 25
80
+ dailyLossLimitPct: 5 # 日亏损限制 (%),默认 5
81
+ maxTradesPerDay: 10 # 日最大交易笔数,默认 10
82
+
83
+ # ── 分类 (可选,展示用) ───────────────────────────────────────
84
+ classification:
85
+ archetype: systematic # systematic | discretionary | hybrid
86
+ market: Crypto # Crypto | US | CN | HK | Forex | Commodity
87
+ assetClasses: [crypto]
88
+ frequency: daily # daily | weekly | monthly
89
+ riskProfile: medium # low | medium | high
90
+ ```
91
+
92
+ ### Identity Fields (FEP v2.0)
93
+
94
+ **必填字段:**
95
+
96
+ - `id`: 策略唯一标识(英文 + 连字符,例如 `fin-dca-basic-test`)
97
+ - `type`: `strategy` | `indicator` | `connector`(默认 `strategy`)
98
+ - `name`: 策略显示名称
99
+ - `version`: 语义化版本号(例如 `"1.0.0"`)
100
+ - `style`: `trend` | `mean-reversion` | `momentum` | `value` | `growth` | `breakout` | `rotation` | `hybrid`
101
+ - `visibility`: `public` | `private` | `unlisted`
102
+ - `summary`: 一句话策略描述
103
+ - `description`: 详细策略说明(支持 Markdown)
104
+ - `license`: `MIT` | `CC-BY-4.0` | `proprietary`
105
+ - `tags`: **字符串数组**,必须使用**行内数组格式**:`tags: [dca, btc, adaptive, crypto]`
106
+ - `author`: 对象格式(必须包含 `name`)
107
+ ```yaml
108
+ author:
109
+ name: "OpenFinClaw" # 必填:作者名
110
+ wallet: "0x..." # 可选:收益分配地址
111
+ ```
112
+ - `changelog`: 变更日志数组(至少包含一条初始版本记录)
113
+ ```yaml
114
+ changelog:
115
+ - version: "1.0.0"
116
+ date: "2025-01-01"
117
+ changes: "Initial release"
118
+ ```
119
+
120
+ ### Backtest Fields (FEP v2.0)
121
+
122
+ **必填字段:**
123
+
124
+ - `symbol`: 交易品种(服务端根据 symbol 自动推断市场类型、数据源、货币、手续费和结算规则)
125
+ - `defaultPeriod.startDate`: 回测开始日期
126
+ - `defaultPeriod.endDate`: 回测结束日期
127
+ - `initialCapital`: 初始资金
128
+
129
+ **可选字段:**
130
+
131
+ - `timeframe`: K线周期,`1m` | `5m` | `15m` | `30m` | `1h` | `4h` | `1d` | `1w`(默认 `1d`)
132
+ - `universe`: 多标的配置(轮动策略用)
133
+ ```yaml
134
+ universe:
135
+ symbols: ["000001.SZ", "000002.SZ", "600519.SH"]
136
+ ```
137
+ - `rebalance`: 再平衡配置(多标的用)
138
+ ```yaml
139
+ rebalance:
140
+ frequency: monthly # daily | weekly | monthly
141
+ maxHoldings: 2 # 最大同时持仓数
142
+ weightMethod: equal # equal | market_cap
143
+ ```
144
+
145
+ **服务端自动推断(用户无需指定):**
146
+
147
+ | 配置项 | 推断规则 |
148
+ | -------- | --------------------------------------------------------------------------------- |
149
+ | 市场类型 | `000001.SZ` → A股, `AAPL` → 美股, `BTC/USDT` → Crypto, `00700.HK` → 港股 |
150
+ | 数据源 | 可识别 symbol → DataHub 真实数据, 未知 → 合成数据 |
151
+ | 货币 | A股 → CNY, 美股 → USD, 港股 → HKD, Crypto → USDT |
152
+ | 手续费 | A股: 佣金+印花税+过户费, 港股: 佣金+印花税+征费, 美股: 零佣金, Crypto: MakerTaker |
153
+ | 结算规则 | A股/ETF → T+1, 其余 → T+0 |
154
+
155
+ ### Symbol 格式
156
+
157
+ | 格式 | 市场 | 示例 |
158
+ | ------------------ | ------ | ------------------------ |
159
+ | `XXX/YYY` | Crypto | `BTC/USDT`, `ETH/BTC` |
160
+ | `6位数.SZ/SH` | A股 | `000001.SZ`, `600519.SH` |
161
+ | `5位数.SH` (5开头) | ETF | `510300.SH` |
162
+ | `000xxx.SH` | 指数 | `000300.SH` |
163
+ | `4-5位数.HK` | 港股 | `00700.HK` |
164
+ | `1-5大写字母` | 美股 | `AAPL`, `NVDA` |
165
+ | `字母+数字.交易所` | 期货 | `IF2503.CFX` |
166
+
167
+ ### Classification (可选)
168
+
169
+ ```yaml
170
+ classification:
171
+ archetype: systematic # systematic | discretionary | hybrid
172
+ market: Crypto # Crypto | US | CN | HK | Forex | Commodity
173
+ assetClasses: [crypto]
174
+ frequency: weekly # daily | weekly | monthly
175
+ riskProfile: medium # low | medium | high
176
+ ```
177
+
178
+ ### Risk (可选)
179
+
180
+ ```yaml
181
+ risk:
182
+ maxDrawdownThreshold: 25 # 最大回撤限制 (%),默认 25
183
+ dailyLossLimitPct: 5 # 日亏损限制 (%),默认 5
184
+ maxTradesPerDay: 10 # 日最大交易笔数,默认 10
185
+ ```
186
+
187
+ ## scripts/strategy.py 要求
188
+
189
+ ### 单标的策略:compute() 函数
190
+
191
+ ```python
192
+ # 模式 A: 无 context(简单策略)
193
+ def compute(data):
194
+ """
195
+ Args:
196
+ data: pandas DataFrame,含列 open, high, low, close, volume
197
+ Returns:
198
+ dict: 键至少包含 action ("buy"|"sell"|"hold"|"target")
199
+ """
200
+ close = data["close"].values
201
+ current_price = float(close[-1])
202
+ return {
203
+ "action": "buy",
204
+ "amount": 100.0,
205
+ "price": current_price,
206
+ "reason": f"Buy at ${current_price:.2f}",
207
+ }
208
+
209
+ # 模式 B: 带 context(推荐)
210
+ def compute(data, context=None):
211
+ """
212
+ Args:
213
+ data: pandas DataFrame
214
+ context: dict with equity, cash, position, bar_index
215
+ """
216
+ position = context.get("position") if context else None
217
+ # ...
218
+ ```
219
+
220
+ ### 多标的策略:select() 函数
221
+
222
+ 用于轮动/选股策略,需在 backtest 中配置 universe:
223
+
224
+ ```python
225
+ def select(universe):
226
+ """
227
+ Args:
228
+ universe: dict[str, pd.DataFrame] - {symbol: DataFrame}
229
+ Returns:
230
+ list[str]: 选中标的列表(按优先级排序)
231
+ """
232
+ scores = []
233
+ for symbol, df in universe.items():
234
+ close = df["close"].values
235
+ if len(close) < 20:
236
+ continue
237
+ momentum = (close[-1] / close[-20]) - 1
238
+ scores.append((symbol, momentum))
239
+
240
+ scores.sort(key=lambda x: x[1], reverse=True)
241
+ return [s[0] for s in scores]
242
+ ```
243
+
244
+ - **允许的导入**:`numpy`, `pandas`, `math`, `statistics`, `datetime`, `collections`, `ta`
245
+ - **禁止(服务器会拒绝)**:
246
+ - Import: `os/subprocess/sys/socket/shutil/ctypes/importlib/signal/threading/multiprocessing/pathlib/tempfile/requests/urllib/http/ftplib/smtplib/xmlrpc/pickle/shelve/marshal/concurrent/asyncio/io`
247
+ - 调用: `eval()`, `exec()`, `compile()`, `open()`, `__import__()`, `getattr()`, `setattr()`, `delattr()`, `vars()`, `dir()`, `breakpoint()`, `exit()`, `quit()`, `input()`, `globals()`, `locals()`
248
+ - 破坏回测: `datetime.now()`, `date.today()`
249
+
250
+ ## 上传前校验与提交流程
251
+
252
+ ### Step 1: 生成或编辑策略包
253
+
254
+ 生成策略包目录(fep.yaml + scripts/strategy.py)。
255
+
256
+ ### Step 2: Self-Validation (自我校验)
257
+
258
+ 1. **Structure:** 必需文件存在:`fep.yaml`, `scripts/strategy.py`。
259
+ 2. **fep.yaml:**
260
+ - Valid YAML, top-level key `fep: "2.0"`
261
+ - `identity`: id, name, type, version, style, visibility, summary, description, license, tags, author.name, changelog (全部必填)
262
+ - `backtest`: symbol, defaultPeriod (startDate/endDate), initialCapital (全部必填)
263
+ 3. **strategy.py:** 定义 `compute(data)` 或 `select(universe)`;返回 dict 包含正确字段;无禁止的导入/调用。
264
+ 4. 调用 `backtest_remote_validate` 传入策略包目录路径 `dirPath`。若返回 `valid: false`,根据 `errors` 修正后再次校验。
265
+ 5. Auto-fix and re-validate up to 3 iterations;若仍失败,向用户清晰解释问题。
266
+
267
+ **不要**在校验未通过时打包上传。
268
+
269
+ ### Step 3: 打包
270
+
271
+ 校验通过后,在策略包目录下执行 `zip -r ../<id>-<version>.zip fep.yaml scripts/`(例如 `fin-dca-basic-test-1.0.0.zip`),得到 ZIP 路径。
272
+
273
+ ### Step 4: 提交
274
+
275
+ 调用 `backtest_remote_submit`,传入 ZIP 的 `filePath`(及可选 engine, budget_cap_usd)。
276
+
277
+ ## 相关 Tools
278
+
279
+ | Tool | 用途 |
280
+ | --------------------------------------------------- | ------------------------------------------------------- |
281
+ | `backtest_remote_validate` | 校验策略包目录格式是否符合 fep v2.0,通过后才可打包上传 |
282
+ | `backtest_remote_submit` | 提交已打包的 ZIP 到远程回测服务 |
283
+ | `backtest_remote_status` / `backtest_remote_report` | 查询任务状态与报告 |
284
+
285
+ 总结:**先按本 skill 生成/补全策略包 → 用 backtest_remote_validate 校验 → 通过后再打包并 backtest_remote_submit**。