@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.
- package/LICENSE +21 -0
- package/README.md +185 -0
- package/index.test.ts +269 -0
- package/index.ts +1005 -0
- package/openclaw.plugin.json +35 -0
- package/package.json +45 -0
- package/skills/openfinclaw/SKILL.md +301 -0
- package/skills/skill-publish/SKILL.md +316 -0
- package/skills/strategy-builder/SKILL.md +555 -0
- package/skills/strategy-fork/SKILL.md +165 -0
- package/skills/strategy-pack/SKILL.md +285 -0
- package/src/cli.ts +321 -0
- package/src/fork.ts +342 -0
- package/src/strategy-storage.test.ts +109 -0
- package/src/strategy-storage.ts +303 -0
- package/src/types.ts +494 -0
- package/src/validate.test.ts +841 -0
- package/src/validate.ts +594 -0
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: strategy-builder
|
|
3
|
+
description: "Strategy builder — turn natural language trading ideas into compliant FEP v2.0 strategy packages for Findoo Backtest (fep.yaml + scripts/strategy.py), with validation and L1/L2 routing."
|
|
4
|
+
metadata:
|
|
5
|
+
openclaw:
|
|
6
|
+
emoji: "🏗️"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Strategy Builder (FEP v2.0)
|
|
10
|
+
|
|
11
|
+
Turn natural language trading ideas into **FEP v2.0** strategy packages compatible with the Findoo Backtest Agent. Generates `fep.yaml` + `scripts/strategy.py` (and optional `risk_manager.py`, `indicators.py`), validates against the spec, and chooses L1 (script) or L2 (agent) engine. Specification reference: **FEP v2.0 协议说明** (docs/finance/FEP-v2.0-协议说明.md).
|
|
12
|
+
|
|
13
|
+
## Prerequisites (tool profile)
|
|
14
|
+
|
|
15
|
+
This skill needs **read** (read files) and **exec** (run shell commands). Ensure the agent has the **coding** tool profile: set `tools.profile: "coding"` or `tools.alsoAllow: ["read", "exec", "write", "edit"]`. See [Strategy builder tools config](https://docs.openclaw.ai/finance/strategy-builder-tools-config) for details. If the user reports "no read/exec tool", tell them to set `tools.profile` to `"coding"` in their OpenClaw config.
|
|
16
|
+
|
|
17
|
+
**No subagent required.** Do strategy creation in the **current session**: use read/write/edit to create `fep.yaml` and `scripts/strategy.py`, and exec for zip/validate. Do not use `sessions_spawn` for strategy building; the user may not have subagent permission.
|
|
18
|
+
|
|
19
|
+
## When to Use
|
|
20
|
+
|
|
21
|
+
**USE this skill when:**
|
|
22
|
+
|
|
23
|
+
- "help me create a strategy" / "build a strategy"
|
|
24
|
+
- "I want to DCA into BTC every week, buy more when it dips"
|
|
25
|
+
- "make me a trend following strategy for ETH"
|
|
26
|
+
- "generate a FEP strategy package" / "生成回测策略包"
|
|
27
|
+
- "I have a trading idea but don't know how to code it"
|
|
28
|
+
- "create a strategy for sideways crypto markets"
|
|
29
|
+
- "turn this idea into a backtest-ready package"
|
|
30
|
+
- "build a grid trading strategy for SOL"
|
|
31
|
+
|
|
32
|
+
## When NOT to Use
|
|
33
|
+
|
|
34
|
+
**DON'T use this skill when:**
|
|
35
|
+
|
|
36
|
+
- User wants to backtest an existing strategy — use fin-backtest or remote backtest tools
|
|
37
|
+
- User wants to evolve/mutate an existing strategy — use fin-strategy-evolution
|
|
38
|
+
- User wants research on which strategy type fits current market — use fin-strategy-research
|
|
39
|
+
- User wants to execute a live trade — use fin-trading
|
|
40
|
+
- User wants portfolio analysis — use fin-portfolio
|
|
41
|
+
|
|
42
|
+
## Tools
|
|
43
|
+
|
|
44
|
+
### Intent & Data Validation
|
|
45
|
+
|
|
46
|
+
- `fin_data_ohlcv` — Verify data availability for requested symbols
|
|
47
|
+
- `fin_data_regime` — Analyze current market regime (informs strategy design)
|
|
48
|
+
- `fin_market_price` — Check current prices and validate symbol existence
|
|
49
|
+
|
|
50
|
+
### Code Generation & Validation
|
|
51
|
+
|
|
52
|
+
- `fin_backtest_run` — Sanity check: quick backtest on 3-month data to verify generated code runs
|
|
53
|
+
- `fin_strategy_create` — Register the generated strategy in the platform
|
|
54
|
+
|
|
55
|
+
### Remote Backtest (fep v2.0, when fin-backtest-remote is enabled)
|
|
56
|
+
|
|
57
|
+
- `backtest_remote_validate` — Validate strategy package directory (fep v2.0) before zip/submit; **use first** when dir is ready
|
|
58
|
+
- `backtest_remote_submit` — Submit strategy ZIP to Findoo Backtest API (after validate + zip)
|
|
59
|
+
- `backtest_remote_status` / `backtest_remote_report` — Query task status and full report
|
|
60
|
+
|
|
61
|
+
### Supporting
|
|
62
|
+
|
|
63
|
+
- `fin_paper_create` — Deploy validated strategy to paper trading (optional follow-up)
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Strategy Package Structure (FEP v2.0)
|
|
68
|
+
|
|
69
|
+
**Required:**
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
<strategy-dir>/
|
|
73
|
+
├── fep.yaml # 策略配置 (必需)
|
|
74
|
+
├── scripts/
|
|
75
|
+
│ └── strategy.py # 策略入口 (必需),必须实现 compute(data) 或 select(universe)
|
|
76
|
+
└── .created-meta.json # 本地元数据 (必需,用于跟踪本地创建的策略)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Optional:**
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
├── scripts/
|
|
83
|
+
│ ├── risk_manager.py # 风控模块
|
|
84
|
+
│ └── indicators.py # 自定义指标
|
|
85
|
+
└── data/ # 自定义数据
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Packaging:** `cd <strategy-dir> && zip -r ../<id>-<version>.zip fep.yaml scripts/` (e.g. `fin-dca-basic-test-1.0.0.zip`)
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## fep.yaml (FEP v2.0)
|
|
93
|
+
|
|
94
|
+
### Minimal (L1 Script)
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
fep: "2.0"
|
|
98
|
+
|
|
99
|
+
# ── 身份标识 (必填) ───────────────────────────────────────
|
|
100
|
+
identity:
|
|
101
|
+
id: fin-dca-basic-test # 必填:策略唯一标识(英文 + 连字符)
|
|
102
|
+
type: strategy # strategy | indicator | connector(默认 strategy)
|
|
103
|
+
name: "DCA Basic Test Strategy" # 必填:策略显示名称
|
|
104
|
+
version: "1.0.0" # 必填:语义化版本号
|
|
105
|
+
style: dca # 必填:trend | mean-reversion | momentum | value | growth | breakout | rotation | hybrid
|
|
106
|
+
visibility: public # 必填:public | private | unlisted
|
|
107
|
+
summary: "Simple DCA strategy for BTC" # 必填:一句话策略描述
|
|
108
|
+
description: "A simple DCA strategy that buys BTC periodically" # 必填:详细策略描述
|
|
109
|
+
license: MIT # 必填:MIT | CC-BY-4.0 | proprietary
|
|
110
|
+
tags: [dca, btc, crypto] # 必填:标签数组
|
|
111
|
+
author:
|
|
112
|
+
name: "OpenFinClaw" # 必填:作者名
|
|
113
|
+
wallet: "0x..." # 可选:收益分配地址
|
|
114
|
+
changelog:
|
|
115
|
+
- version: "1.0.0"
|
|
116
|
+
date: "2025-01-01"
|
|
117
|
+
changes: "Initial release"
|
|
118
|
+
|
|
119
|
+
# ── 技术配置 (可选,有默认值) ───────────────────────────────
|
|
120
|
+
technical:
|
|
121
|
+
language: python # 默认 python
|
|
122
|
+
entryPoint: strategy.py # 默认 strategy.py
|
|
123
|
+
|
|
124
|
+
# ── 策略参数 (可选) ───────────────────────────────────────
|
|
125
|
+
parameters:
|
|
126
|
+
- name: base_amount
|
|
127
|
+
default: 100
|
|
128
|
+
type: number
|
|
129
|
+
label: "基础定投金额"
|
|
130
|
+
range: { min: 10, max: 10000 }
|
|
131
|
+
|
|
132
|
+
# ── 回测配置 (必填) ───────────────────────────────────────
|
|
133
|
+
backtest:
|
|
134
|
+
symbol: "BTC/USDT" # 必填:交易品种(服务端自动推断市场、货币、手续费)
|
|
135
|
+
timeframe: 1d # 可选:1m | 5m | 15m | 30m | 1h | 4h | 1d | 1w(默认 1d)
|
|
136
|
+
defaultPeriod:
|
|
137
|
+
startDate: "2025-01-01"
|
|
138
|
+
endDate: "2026-01-01"
|
|
139
|
+
initialCapital: 10000 # 必填:初始资金
|
|
140
|
+
|
|
141
|
+
# ── 风控配置 (可选) ───────────────────────────────────────
|
|
142
|
+
risk:
|
|
143
|
+
maxDrawdownThreshold: 25 # 最大回撤限制 (%)
|
|
144
|
+
dailyLossLimitPct: 5 # 日亏损限制 (%)
|
|
145
|
+
maxTradesPerDay: 10 # 日最大交易笔数
|
|
146
|
+
|
|
147
|
+
# ── 分类 (必填) ───────────────────────────────────────
|
|
148
|
+
classification:
|
|
149
|
+
archetype: systematic # 必填: systematic | discretionary | hybrid
|
|
150
|
+
market: Crypto # 必填: Crypto | US | CN | HK | Forex | Commodity
|
|
151
|
+
assetClasses: [crypto] # 必填: 资产类别数组
|
|
152
|
+
frequency: daily # 必填: daily | weekly | monthly
|
|
153
|
+
riskProfile: medium # 必填: low | medium | high
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Version Increment Rule
|
|
157
|
+
|
|
158
|
+
**When the same strategy `id` is modified, increment `identity.version`:**
|
|
159
|
+
|
|
160
|
+
- Semver format `X.Y.Z`: increment `Z` (patch) for minor changes, `Y` for new features, `X` for breaking changes
|
|
161
|
+
- Example: `1.0.0` → `1.0.1` (parameter tweak), `1.1.0` (new indicator), `2.0.0` (logic redesign)
|
|
162
|
+
- If strategy `id` already exists in the registry, always bump version before saving/zipping
|
|
163
|
+
|
|
164
|
+
### Identity Fields (FEP v2.0)
|
|
165
|
+
|
|
166
|
+
**必填字段:**
|
|
167
|
+
|
|
168
|
+
- `id`: 策略唯一标识(英文 + 连字符,例如 `fin-dca-basic-test`)
|
|
169
|
+
- `type`: `strategy` | `indicator` | `connector`(默认 `strategy`)
|
|
170
|
+
- `name`: 策略显示名称
|
|
171
|
+
- `version`: 语义化版本号(例如 `"1.0.0"`)
|
|
172
|
+
- `style`: `trend` | `mean-reversion` | `momentum` | `value` | `growth` | `breakout` | `rotation` | `hybrid`
|
|
173
|
+
- `visibility`: `public` | `private` | `unlisted`
|
|
174
|
+
- `summary`: 一句话策略描述
|
|
175
|
+
- `description`: 详细策略说明(支持 Markdown)
|
|
176
|
+
- `license`: `MIT` | `CC-BY-4.0` | `proprietary`
|
|
177
|
+
- `tags`: **字符串数组**,必须使用**行内数组格式**:`tags: [dca, btc, adaptive, crypto]`
|
|
178
|
+
- `author`: 对象格式(必须包含 `name`)
|
|
179
|
+
```yaml
|
|
180
|
+
author:
|
|
181
|
+
name: "OpenFinClaw" # 必填:作者名
|
|
182
|
+
wallet: "0x..." # 可选:收益分配地址
|
|
183
|
+
```
|
|
184
|
+
- `changelog`: 变更日志数组(至少包含一条初始版本记录)
|
|
185
|
+
```yaml
|
|
186
|
+
changelog:
|
|
187
|
+
- version: "1.0.0"
|
|
188
|
+
date: "2026-01-01"
|
|
189
|
+
changes: "Initial release"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**可选字段:**
|
|
193
|
+
|
|
194
|
+
- `createdAt`: `"2025-01-01"` (YYYY-MM-DD)
|
|
195
|
+
- `updatedAt`: `"2025-06-01"` (YYYY-MM-DD)
|
|
196
|
+
|
|
197
|
+
### Backtest Fields (FEP v2.0)
|
|
198
|
+
|
|
199
|
+
**必填字段:**
|
|
200
|
+
|
|
201
|
+
- `symbol`: 交易品种(服务端根据 symbol 自动推断市场类型、数据源、货币、手续费和结算规则)
|
|
202
|
+
- `defaultPeriod.startDate`: 回测开始日期
|
|
203
|
+
- `defaultPeriod.endDate`: 回测结束日期
|
|
204
|
+
- `initialCapital`: 初始资金
|
|
205
|
+
|
|
206
|
+
**可选字段:**
|
|
207
|
+
|
|
208
|
+
- `timeframe`: K线周期,`1m` | `5m` | `15m` | `30m` | `1h` | `4h` | `1d` | `1w`(默认 `1d`)
|
|
209
|
+
- `universe`: 多标的配置(轮动策略用)
|
|
210
|
+
```yaml
|
|
211
|
+
universe:
|
|
212
|
+
symbols: ["000001.SZ", "000002.SZ", "600519.SH"]
|
|
213
|
+
```
|
|
214
|
+
- `rebalance`: 再平衡配置(多标的用)
|
|
215
|
+
```yaml
|
|
216
|
+
rebalance:
|
|
217
|
+
frequency: monthly # daily | weekly | monthly
|
|
218
|
+
maxHoldings: 2 # 最大同时持仓数
|
|
219
|
+
weightMethod: equal # equal | market_cap
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**服务端自动推断(用户无需指定):**
|
|
223
|
+
|
|
224
|
+
| 配置项 | 推断规则 |
|
|
225
|
+
| -------- | --------------------------------------------------------------------------------- |
|
|
226
|
+
| 市场类型 | `000001.SZ` → A股, `AAPL` → 美股, `BTC/USDT` → Crypto, `00700.HK` → 港股 |
|
|
227
|
+
| 数据源 | 可识别 symbol → DataHub 真实数据, 未知 → 合成数据 |
|
|
228
|
+
| 货币 | A股 → CNY, 美股 → USD, 港股 → HKD, Crypto → USDT |
|
|
229
|
+
| 手续费 | A股: 佣金+印花税+过户费, 港股: 佣金+印花税+征费, 美股: 零佣金, Crypto: MakerTaker |
|
|
230
|
+
| 结算规则 | A股/ETF → T+1, 其余 → T+0 |
|
|
231
|
+
|
|
232
|
+
### Symbol 格式
|
|
233
|
+
|
|
234
|
+
| 格式 | 市场 | 示例 |
|
|
235
|
+
| ------------------ | ------ | ------------------------ |
|
|
236
|
+
| `XXX/YYY` | Crypto | `BTC/USDT`, `ETH/BTC` |
|
|
237
|
+
| `6位数.SZ/SH` | A股 | `000001.SZ`, `600519.SH` |
|
|
238
|
+
| `5位数.SH` (5开头) | ETF | `510300.SH` |
|
|
239
|
+
| `000xxx.SH` | 指数 | `000300.SH` |
|
|
240
|
+
| `4-5位数.HK` | 港股 | `00700.HK` |
|
|
241
|
+
| `1-5大写字母` | 美股 | `AAPL`, `NVDA` |
|
|
242
|
+
| `字母+数字.交易所` | 期货 | `IF2503.CFX` |
|
|
243
|
+
|
|
244
|
+
### Classification (必填)
|
|
245
|
+
|
|
246
|
+
```yaml
|
|
247
|
+
classification:
|
|
248
|
+
archetype: systematic # 必填: systematic | discretionary | hybrid
|
|
249
|
+
market: Crypto # 必填: Crypto | US | CN | HK | Forex | Commodity
|
|
250
|
+
assetClasses: [crypto] # 必填: 资产类别数组
|
|
251
|
+
frequency: daily # 必填: daily | weekly | monthly
|
|
252
|
+
riskProfile: medium # 必填: low | medium | high
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Risk (可选)
|
|
256
|
+
|
|
257
|
+
```yaml
|
|
258
|
+
risk:
|
|
259
|
+
maxDrawdownThreshold: 25 # 最大回撤限制 (%),默认 25
|
|
260
|
+
dailyLossLimitPct: 5 # 日亏损限制 (%),默认 5
|
|
261
|
+
maxTradesPerDay: 10 # 日最大交易笔数,默认 10
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Paper (可选)
|
|
265
|
+
|
|
266
|
+
```yaml
|
|
267
|
+
paper:
|
|
268
|
+
barIntervalSeconds: 60 # 行情轮询间隔(秒),默认 60
|
|
269
|
+
maxDurationHours: 24 # 最大运行时长,默认 24
|
|
270
|
+
warmupBars: 100 # 预热 K 线数,默认 100
|
|
271
|
+
timeframe: 1d # 模拟盘 K 线周期
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## scripts/strategy.py — Mandatory Contract
|
|
277
|
+
|
|
278
|
+
### 单标的策略:compute() 函数
|
|
279
|
+
|
|
280
|
+
**Must** implement a single entry function:
|
|
281
|
+
|
|
282
|
+
```python
|
|
283
|
+
# 模式 A: 无 context(简单策略)
|
|
284
|
+
def compute(data):
|
|
285
|
+
"""
|
|
286
|
+
Args:
|
|
287
|
+
data: pandas DataFrame, 包含 OHLCV 列 (open, high, low, close, volume)
|
|
288
|
+
Returns:
|
|
289
|
+
dict: {"action": "buy"|"sell"|"hold"|"target", ...}
|
|
290
|
+
"""
|
|
291
|
+
close = data["close"].values
|
|
292
|
+
current_price = float(close[-1])
|
|
293
|
+
return {
|
|
294
|
+
"action": "buy",
|
|
295
|
+
"amount": 100.0,
|
|
296
|
+
"price": current_price,
|
|
297
|
+
"reason": f"Buy at ${current_price:.2f}",
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
# 模式 B: 带 context(推荐,可获取仓位和资金信息)
|
|
301
|
+
def compute(data, context=None):
|
|
302
|
+
"""
|
|
303
|
+
Args:
|
|
304
|
+
data: pandas DataFrame
|
|
305
|
+
context: dict with equity, cash, position, bar_index
|
|
306
|
+
"""
|
|
307
|
+
position = context.get("position") if context else None
|
|
308
|
+
# ...
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**context 结构:**
|
|
312
|
+
|
|
313
|
+
```python
|
|
314
|
+
{
|
|
315
|
+
"equity": 95000.0, # 当前账户净值
|
|
316
|
+
"cash": 45000.0, # 可用现金
|
|
317
|
+
"initial_capital": 100000.0, # 初始资金
|
|
318
|
+
"position": { # 有持仓时
|
|
319
|
+
"side": "long",
|
|
320
|
+
"quantity": 100.0,
|
|
321
|
+
"market_value": 50000.0
|
|
322
|
+
} or None, # 无持仓时
|
|
323
|
+
"bar_index": 150 # 全局 K 线索引
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**信号返回格式:**
|
|
328
|
+
|
|
329
|
+
| action | 必填字段 | 可选字段 | 说明 |
|
|
330
|
+
| -------- | -------------------------- | ------------------------- | ----------------------------- |
|
|
331
|
+
| `buy` | amount, price | reason | 按金额买入 |
|
|
332
|
+
| `sell` | — | percent, quantity, reason | 无参数=全仓卖, percent=按比例 |
|
|
333
|
+
| `hold` | — | reason | 不操作 |
|
|
334
|
+
| `target` | target_pct 或 target_value | reason | 调仓到目标权重/金额 |
|
|
335
|
+
|
|
336
|
+
### 多标的策略:select() 函数
|
|
337
|
+
|
|
338
|
+
用于轮动/选股策略,需在 backtest 中配置 universe:
|
|
339
|
+
|
|
340
|
+
```python
|
|
341
|
+
def select(universe):
|
|
342
|
+
"""
|
|
343
|
+
Args:
|
|
344
|
+
universe: dict[str, pd.DataFrame] - {symbol: DataFrame}
|
|
345
|
+
Returns:
|
|
346
|
+
list[str]: 选中标的列表(按优先级排序)
|
|
347
|
+
"""
|
|
348
|
+
scores = []
|
|
349
|
+
for symbol, df in universe.items():
|
|
350
|
+
close = df["close"].values
|
|
351
|
+
if len(close) < 20:
|
|
352
|
+
continue
|
|
353
|
+
momentum = (close[-1] / close[-20]) - 1
|
|
354
|
+
scores.append((symbol, momentum))
|
|
355
|
+
|
|
356
|
+
scores.sort(key=lambda x: x[1], reverse=True)
|
|
357
|
+
return [s[0] for s in scores] # 引擎自动截取 maxHoldings 个
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
- **Allowed imports:** `numpy`, `pandas`, `math`, `statistics`, `datetime`, `collections`, `ta`
|
|
361
|
+
- **Forbidden (server will reject):** `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`, `eval()`, `exec()`, `compile()`, `open()`, `__import__()`, `getattr()`, `setattr()`, `delattr()`, `vars()`, `dir()`, `breakpoint()`, `exit()`, `quit()`, `input()`, `globals()`, `locals()`
|
|
362
|
+
- **Forbidden (breaks backtest):** `datetime.now()`, `date.today()`
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Builder Pipeline
|
|
367
|
+
|
|
368
|
+
### Step 1: Intent Collection (Conversational)
|
|
369
|
+
|
|
370
|
+
Extract key dimensions:
|
|
371
|
+
|
|
372
|
+
| Dimension | Example |
|
|
373
|
+
| -------------- | --------------------------------- |
|
|
374
|
+
| Asset | BTC, ETH, AAPL, 沪深 300 |
|
|
375
|
+
| Frequency | daily, weekly, monthly |
|
|
376
|
+
| Core idea | buy dips, trend follow, grid, DCA |
|
|
377
|
+
| Capital | $10,000 |
|
|
378
|
+
| Risk tolerance | 25% max drawdown |
|
|
379
|
+
| Time horizon | 2024-01-01 to 2024-12-31 |
|
|
380
|
+
| Market | Crypto, US, CN, HK |
|
|
381
|
+
|
|
382
|
+
Ask clarifying questions if the idea is vague (e.g. "buy when cheap" → RSI oversold? below MA? fixed schedule?).
|
|
383
|
+
|
|
384
|
+
### Step 2: Technical Design (Propose & Confirm)
|
|
385
|
+
|
|
386
|
+
Propose: strategy archetype (DCA, trend, mean-reversion, momentum, grid), indicators (RSI, EMA, MACD, etc.), entry/exit logic, position sizing, risk controls, market adaptations. **Wait for user confirmation** before generating code.
|
|
387
|
+
|
|
388
|
+
### Step 2.5: Determine Target Directory
|
|
389
|
+
|
|
390
|
+
**All locally created strategies MUST be saved to the standard path:**
|
|
391
|
+
|
|
392
|
+
```
|
|
393
|
+
~/.openfinclaw/workspace/strategies/{YYYY-MM-DD}/{slugified-name}/
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**Path rules:**
|
|
397
|
+
|
|
398
|
+
- `{YYYY-MM-DD}`: Current date (e.g., `2026-03-19`), organizes strategies by creation date
|
|
399
|
+
- `{slugified-name}`: Lowercase, spaces/underscores to hyphens, max 40 chars (e.g., `btc-adaptive-dca`)
|
|
400
|
+
- **ALWAYS** create the date directory if it does not exist
|
|
401
|
+
- **NEVER** save strategies to arbitrary directories like `~/clawd`, `~/projects`, etc.
|
|
402
|
+
|
|
403
|
+
**Directory creation sequence:**
|
|
404
|
+
|
|
405
|
+
1. Compute `dateStr = formatDate(new Date())` → `"YYYY-MM-DD"`
|
|
406
|
+
2. Compute `slug = slugifyName(strategyName)` → lowercase-hyphenated
|
|
407
|
+
3. `rootDir = path.join(homedir(), ".openfinclaw", "workspace", "strategies")`
|
|
408
|
+
4. `dateDir = path.join(rootDir, dateStr)` — create if not exists
|
|
409
|
+
5. `targetDir = path.join(dateDir, slug)` — final strategy directory
|
|
410
|
+
|
|
411
|
+
**Example:**
|
|
412
|
+
|
|
413
|
+
```
|
|
414
|
+
Strategy name: "BTC Adaptive DCA"
|
|
415
|
+
Date: 2026-03-19
|
|
416
|
+
Target dir: ~/.openfinclaw/workspace/strategies/2026-03-19/btc-adaptive-dca/
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
**Metadata file (.created-meta.json):** After creating the strategy files, also generate this metadata file in the strategy directory:
|
|
420
|
+
|
|
421
|
+
```json
|
|
422
|
+
{
|
|
423
|
+
"name": "fin-btc-adaptive-dca",
|
|
424
|
+
"displayName": "BTC Adaptive DCA",
|
|
425
|
+
"createdAt": "2026-03-19T10:30:00.000Z",
|
|
426
|
+
"version": "1.0.0"
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Step 3: Code Generation (FEP v2.0)
|
|
431
|
+
|
|
432
|
+
Generate:
|
|
433
|
+
|
|
434
|
+
1. **fep.yaml** — `fep: "2.0"`, 包含以下部分:
|
|
435
|
+
- **identity** (必填): id, type, name, version, style, visibility, summary, description, license, tags, author (对象格式,必须包含 name), changelog (至少一条记录)
|
|
436
|
+
- **technical** (可选): language, entryPoint
|
|
437
|
+
- **parameters** (可选): 策略参数数组
|
|
438
|
+
- **backtest** (必填): symbol, defaultPeriod, initialCapital; 可选 timeframe, universe, rebalance
|
|
439
|
+
- **classification** (必填): archetype, market, assetClasses, frequency, riskProfile
|
|
440
|
+
- **risk** (可选): 风控配置
|
|
441
|
+
|
|
442
|
+
**生成规则:**
|
|
443
|
+
- `fep` 版本必须是 `"2.0"`
|
|
444
|
+
- `backtest.defaultPeriod.endDate` 默认使用当前日期(格式 `YYYY-MM-DD`)
|
|
445
|
+
- `backtest.defaultPeriod.startDate` 根据用户描述选择合理区间(例如最近 6–12 个月)
|
|
446
|
+
- `backtest.symbol` 必填,服务端自动推断市场和手续费
|
|
447
|
+
- **classification 必填字段及默认值:**
|
|
448
|
+
- `archetype`: 默认 `systematic`(除非用户明确需要主观判断)
|
|
449
|
+
- `market`: 根据标的自动推断(BTC/ETH → `Crypto`,AAPL → `US` 等)
|
|
450
|
+
- `assetClasses`: 根据标的自动推断(BTC/ETH → `[crypto]`,AAPL → `[equity]`)
|
|
451
|
+
- `frequency`: 默认 `daily`(日频)
|
|
452
|
+
- `riskProfile`: 默认 `medium`
|
|
453
|
+
- **版本递增规则:** 如果策略 `id` 已存在(用户修改现有策略),必须递增 `identity.version`
|
|
454
|
+
- **默认作者:** `identity.author.name` 默认为 `"OpenFinClaw"`,除非用户指定其他作者
|
|
455
|
+
- **默认可见性:** `identity.visibility` 默认为 `"public"`(公开策略)
|
|
456
|
+
- **默认许可证:** `identity.license` 默认为 `"MIT"`
|
|
457
|
+
- **默认风格:** `identity.style` 根据策略类型自动选择
|
|
458
|
+
- **tags 格式:** 必须使用行内数组 `tags: [dca, btc, crypto]`
|
|
459
|
+
|
|
460
|
+
2. **scripts/strategy.py** — Must define `compute(data)` or `compute(data, context=None)` returning signal dict, or `select(universe)` for multi-asset strategies. Use only allowed imports; no forbidden patterns.
|
|
461
|
+
|
|
462
|
+
3. **.created-meta.json** — Metadata file for local strategy tracking (required for all locally created strategies):
|
|
463
|
+
|
|
464
|
+
```json
|
|
465
|
+
{
|
|
466
|
+
"name": "fin-btc-adaptive-dca",
|
|
467
|
+
"displayName": "BTC Adaptive DCA",
|
|
468
|
+
"createdAt": "2026-03-19T10:30:00.000Z",
|
|
469
|
+
"version": "1.0.0"
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
4. **Optional:** scripts/indicators.py, scripts/risk_manager.py (if design needs them; entry contract remains `compute(data)` in strategy.py).
|
|
474
|
+
|
|
475
|
+
Present the package structure and wait for confirmation before validation.
|
|
476
|
+
|
|
477
|
+
### Step 4: Self-Validation
|
|
478
|
+
|
|
479
|
+
1. **Structure:** Required files exist: `fep.yaml`, `scripts/strategy.py`, `.created-meta.json`.
|
|
480
|
+
2. **fep.yaml:**
|
|
481
|
+
- Valid YAML, top-level key `fep: "2.0"`
|
|
482
|
+
- `identity`: id, name, type, version, style, visibility, summary, description, license, tags, author.name, changelog (全部必填)
|
|
483
|
+
- `backtest`: symbol, defaultPeriod (startDate/endDate), initialCapital (全部必填)
|
|
484
|
+
- `classification`: archetype, market, assetClasses, frequency, riskProfile (全部必填)
|
|
485
|
+
3. **strategy.py:** Defines `compute(data)` or `select(universe)`; return dict has required fields; no forbidden imports/calls.
|
|
486
|
+
4. **.created-meta.json:** Valid JSON with `name`, `displayName`, `createdAt`, `version` fields.
|
|
487
|
+
5. **Target directory:** Must be under `~/.openfinclaw/workspace/strategies/{YYYY-MM-DD}/`.
|
|
488
|
+
6. If **fin-backtest-remote** is available: call `backtest_remote_validate` with the strategy directory path; if `valid: false`, fix `errors` and re-validate. Do not zip/submit until validation passes.
|
|
489
|
+
7. **Sanity run:** If local backtest is available (`fin_backtest_run`), run on a short period to confirm code executes.
|
|
490
|
+
|
|
491
|
+
Auto-fix and re-validate up to 3 iterations; if still failing, explain clearly to the user.
|
|
492
|
+
|
|
493
|
+
### Step 5: L1 vs L2 Routing
|
|
494
|
+
|
|
495
|
+
| Signal | L1 (script) | L2 (agent) |
|
|
496
|
+
| ----------------- | ------------------------- | ------------------------------------- |
|
|
497
|
+
| Decision logic | Fully deterministic rules | Requires judgment, context |
|
|
498
|
+
| Engine in fep/API | `engine: script` or omit | `engine: agent`, `agent.budgetCapUsd` |
|
|
499
|
+
| Cost | No LLM cost | LLM budget cap |
|
|
500
|
+
|
|
501
|
+
**Default: L1.** Only set L2 (agent section in fep.yaml, engine=agent on submit) when the user explicitly wants agent involvement or strategy benefits from LLM analysis.
|
|
502
|
+
|
|
503
|
+
### Step 6: Delivery & Optional Remote Backtest
|
|
504
|
+
|
|
505
|
+
Present the package and next steps:
|
|
506
|
+
|
|
507
|
+
- **Local/registration:** Run backtest (fin-backtest), deploy to paper (fin_paper_create), tweak parameters in fep.yaml.
|
|
508
|
+
- **Remote Findoo Backtest (fep v2.0):** If user wants to submit to the remote server:
|
|
509
|
+
1. Ensure directory is validated (`backtest_remote_validate`)
|
|
510
|
+
2. Zip: `zip -r ../<id>-<version>.zip fep.yaml scripts/` (e.g. `fin-dca-basic-test-1.0.0.zip`)
|
|
511
|
+
3. Submit with `backtest_remote_submit` (filePath, optional engine, budget_cap_usd)
|
|
512
|
+
4. Poll with `backtest_remote_status`, fetch report with `backtest_remote_report` when status is completed
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
## Strategy Template Library
|
|
517
|
+
|
|
518
|
+
| Template | style | market | Entry Function |
|
|
519
|
+
| -------------------- | -------------- | ------ | -------------- |
|
|
520
|
+
| Simple DCA | dca | Crypto | compute() |
|
|
521
|
+
| Adaptive DCA | dca | Crypto | compute() |
|
|
522
|
+
| EMA Crossover | trend | Crypto | compute() |
|
|
523
|
+
| RSI Bounce | mean-reversion | Crypto | compute() |
|
|
524
|
+
| MACD Momentum | momentum | Crypto | compute() |
|
|
525
|
+
| Grid Trading | hybrid | Crypto | compute() |
|
|
526
|
+
| Multi-Asset Rotation | rotation | CN | select() |
|
|
527
|
+
| Multi-Factor | hybrid | Crypto | compute() |
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## Market Adaptation Rules
|
|
532
|
+
|
|
533
|
+
| Market | Fee / Settlement | Lot / Limits | Special |
|
|
534
|
+
| ------------ | ---------------- | -------------- | ---------------------------------- |
|
|
535
|
+
| Crypto | ~0.1%, T+0 | 0.001+ | 24/7 |
|
|
536
|
+
| US Stock | ~0.1%, T+0 | 1 share | Pre/post hours |
|
|
537
|
+
| A-Share (CN) | ~0.154%, **T+1** | **100 shares** | **±10%/±20%**, stamp tax sell-only |
|
|
538
|
+
| HK | ~0.24%, T+0/T+2 | Variable | Lunch break |
|
|
539
|
+
|
|
540
|
+
For A-shares: T+1 signal delay, lot rounding to 100, price limit filters.
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
## Response Guidelines
|
|
545
|
+
|
|
546
|
+
- Understand the user's idea; ask questions if vague.
|
|
547
|
+
- Present technical design in plain language and wait for confirmation before code.
|
|
548
|
+
- After generation, show package structure (fep.yaml + scripts/strategy.py).
|
|
549
|
+
- Run validation and report pass/fail; use `backtest_remote_validate` when available before any remote submit.
|
|
550
|
+
- Prefer L1 when sufficient; suggest L2 only when needed.
|
|
551
|
+
- End with clear next steps (backtest, paper, remote submit, or iterate).
|
|
552
|
+
|
|
553
|
+
## Risk Disclosures
|
|
554
|
+
|
|
555
|
+
> Generated strategies are based on historical patterns and user ideas. They require backtesting and paper trading before real capital. The builder produces code from rules and does not guarantee profitability. Validate with backtest and paper trading before going live.
|