@openfinclaw/openfinclaw-strategy 2026.3.27 → 2026.3.271

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/README.md CHANGED
@@ -80,7 +80,7 @@ openclaw strategy remove <name-or-id> --force
80
80
  从 https://hub.openfinclaw.ai 获取 API Key(以 `fch_` 开头),一个 Key 即可使用所有功能:
81
81
 
82
82
  ```bash
83
- openclaw config set plugins.entries.openfinclaw.config.apiKey YOUR_API_KEY
83
+ openclaw config set plugins.entries.openfinclaw-strategy.config.apiKey YOUR_API_KEY
84
84
  ```
85
85
 
86
86
  或使用环境变量:
package/index.test.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Unit tests for openfinclaw plugin: registration, config resolution, and tool execution with mocked HTTP.
3
3
  */
4
- import type { OpenClawPluginApi } from "openfinclaw/plugin-sdk";
4
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
5
5
  import { afterEach, describe, expect, it, vi } from "vitest";
6
6
  import plugin from "./index.js";
7
7
 
@@ -32,7 +32,7 @@ function createFakeApi(pluginConfig: Record<string, unknown>): {
32
32
  } {
33
33
  const tools = new Map<string, Tool>();
34
34
  const api = {
35
- id: "openfinclaw",
35
+ id: "openfinclaw-strategy",
36
36
  name: "OpenFinClaw",
37
37
  source: "test",
38
38
  config: {},
@@ -66,7 +66,7 @@ describe("openfinclaw plugin", () => {
66
66
  });
67
67
 
68
68
  it("has correct plugin metadata", () => {
69
- expect(plugin.id).toBe("openfinclaw");
69
+ expect(plugin.id).toBe("openfinclaw-strategy");
70
70
  expect(plugin.name).toBe("OpenFinClaw");
71
71
  });
72
72
 
package/index.ts CHANGED
@@ -8,7 +8,7 @@ import type { Command } from "commander";
8
8
  * - Dashboard: embedded HTTP server at http://127.0.0.1:<httpPort> (default 18792)
9
9
  * Supports FEP v2.0 protocol for strategy packages.
10
10
  */
11
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
11
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
12
12
  import { registerStrategyCli } from "./src/cli.js";
13
13
  import { resolvePluginConfig } from "./src/config.js";
14
14
  import { registerDatahubTools } from "./src/datahub/tools.js";
@@ -17,7 +17,7 @@ import { startHttpServer } from "./src/http/server.js";
17
17
  import { registerStrategyTools } from "./src/strategy/tools.js";
18
18
 
19
19
  const openfinclawPlugin = {
20
- id: "openfinclaw",
20
+ id: "openfinclaw-strategy",
21
21
  name: "OpenFinClaw",
22
22
  description:
23
23
  "Unified financial tools: strategy publishing/fork/validation, market data (price/K-line/crypto/compare/search). Single API key for Hub and DataHub.",
@@ -42,6 +42,7 @@ const openfinclawPlugin = {
42
42
  program,
43
43
  config,
44
44
  logger: api.logger,
45
+ db,
45
46
  }),
46
47
  { commands: ["strategy"] },
47
48
  );
@@ -1,10 +1,10 @@
1
1
  {
2
- "id": "openfinclaw",
2
+ "id": "openfinclaw-strategy",
3
3
  "name": "OpenFinClaw",
4
4
  "description": "Unified financial tools: market data (price/K-line/crypto/compare/search), strategy publishing, fork, and validation. Single API key for Hub and DataHub.",
5
5
  "kind": "financial",
6
6
  "version": "2026.3.25",
7
- "skills": ["./skills"],
7
+ "skills": ["."],
8
8
  "configSchema": {
9
9
  "type": "object",
10
10
  "properties": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfinclaw/openfinclaw-strategy",
3
- "version": "2026.3.27",
3
+ "version": "2026.3.271",
4
4
  "description": "OpenFinClaw - Unified financial tools: market data (price/K-line/crypto/compare/search), strategy publishing, fork, and validation. Single API key for Hub and DataHub.",
5
5
  "keywords": [
6
6
  "backtest",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: fin-price-check
3
3
  description: "Quick price lookup for any asset — stocks, crypto, indices. Use when user asks '什么价格', 'how much is', 'current price of', or any simple price query. Returns latest price, volume, and date."
4
- metadata: { "openclaw": { "emoji": "💰", "requires": { "extensions": ["openfinclaw"] } } }
4
+ metadata: { "openclaw": { "emoji": "💰", "requires": { "extensions": ["openfinclaw-strategy"] } } }
5
5
  ---
6
6
 
7
7
  # Price Check
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: skill-publish
3
3
  description: "Skill Publishing Agent. Use when the user wants to publish a strategy to the server, check publish/backtest status, or view backtest report. Flow: validate → zip → publish → poll verify → get report. Supports FEP v2.0 protocol."
4
- metadata: { "openclaw": { "requires": { "extensions": ["openfinclaw"] } } }
4
+ metadata: { "openclaw": { "requires": { "extensions": ["openfinclaw-strategy"] } } }
5
5
  ---
6
6
 
7
7
  # Skill Publishing
@@ -149,7 +149,7 @@ Agent:
149
149
  1. **API Key**: Fork 操作需要配置 API Key
150
150
 
151
151
  ```bash
152
- openclaw config set plugins.entries.openfinclaw.config.apiKey YOUR_KEY
152
+ openclaw config set plugins.entries.openfinclaw-strategy.config.apiKey YOUR_KEY
153
153
  ```
154
154
 
155
155
  2. **同名冲突**: 如果两个策略名称相同,会自动添加短 ID 后缀区分
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: strategy-pack
3
3
  description: "Create and validate 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 publishing. Always validate with skill_validate before zipping and publishing."
4
- metadata: { "openclaw": { "requires": { "extensions": ["openfinclaw"] } } }
4
+ metadata: { "openclaw": { "requires": { "extensions": ["openfinclaw-strategy"] } } }
5
5
  ---
6
6
 
7
7
  # 策略包生成与校验 (FEP v2.0)
package/src/cli.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * CLI commands for strategy management.
3
3
  */
4
+ import { randomUUID } from "node:crypto";
5
+ import type { DatabaseSync } from "node:sqlite";
4
6
  import type { Command } from "commander";
7
+ import { insertActivityLog } from "./db/repositories.js";
5
8
  import { forkStrategy, fetchStrategyInfo } from "./strategy/fork.js";
6
9
  import { listLocalStrategies, findLocalStrategy, removeLocalStrategy } from "./strategy/storage.js";
7
10
  import type { UnifiedPluginConfig, LeaderboardResponse, BoardType } from "./types.js";
@@ -12,12 +15,33 @@ type Logger = {
12
15
  error: (message: string) => void;
13
16
  };
14
17
 
18
+ /** Log a CLI command execution to agent_activity_log. */
19
+ function logCli(
20
+ db: DatabaseSync,
21
+ action: string,
22
+ params: Record<string, unknown>,
23
+ startMs: number,
24
+ error?: string,
25
+ ): void {
26
+ insertActivityLog(db, {
27
+ id: randomUUID(),
28
+ timestamp: new Date().toISOString(),
29
+ category: "strategy",
30
+ action: `cli:${action}`,
31
+ detail: error
32
+ ? `ERROR (${Date.now() - startMs}ms): ${error}`
33
+ : `OK (${Date.now() - startMs}ms)`,
34
+ metadata_json: JSON.stringify({ source: "cli", params }),
35
+ });
36
+ }
37
+
15
38
  export function registerStrategyCli(params: {
16
39
  program: Command;
17
40
  config: UnifiedPluginConfig;
18
41
  logger: Logger;
42
+ db: DatabaseSync;
19
43
  }) {
20
- const { program, config } = params;
44
+ const { program, config, db } = params;
21
45
 
22
46
  const root = program
23
47
  .command("strategy")
@@ -31,6 +55,7 @@ export function registerStrategyCli(params: {
31
55
  .option("-o, --offset <number>", "Offset for pagination", "0")
32
56
  .action(
33
57
  async (boardType: BoardType = "composite", options: { limit?: string; offset?: string }) => {
58
+ const startMs = Date.now();
34
59
  const limit = Math.min(Math.max(Number(options.limit) || 20, 1), 100);
35
60
  const offset = Math.max(Number(options.offset) || 0, 0);
36
61
 
@@ -46,6 +71,13 @@ export function registerStrategyCli(params: {
46
71
  });
47
72
 
48
73
  if (!response.ok) {
74
+ logCli(
75
+ db,
76
+ "leaderboard",
77
+ { boardType, limit, offset },
78
+ startMs,
79
+ `HTTP ${response.status}`,
80
+ );
49
81
  console.error(`✗ 请求失败: HTTP ${response.status}`);
50
82
  process.exitCode = 1;
51
83
  return;
@@ -92,7 +124,9 @@ export function registerStrategyCli(params: {
92
124
  console.log("");
93
125
  console.log("使用 openclaw strategy show <id> --remote 查看详情");
94
126
  console.log("使用 openclaw strategy fork <id> 下载策略(需要 API Key)");
127
+ logCli(db, "leaderboard", { boardType, limit, offset }, startMs);
95
128
  } catch (err) {
129
+ logCli(db, "leaderboard", { boardType, limit, offset }, startMs, String(err));
96
130
  console.error(`✗ 请求失败: ${err instanceof Error ? err.message : String(err)}`);
97
131
  process.exitCode = 1;
98
132
  }
@@ -107,6 +141,7 @@ export function registerStrategyCli(params: {
107
141
  .option("--date <date>", "Date directory (YYYY-MM-DD, default: today)")
108
142
  .option("-y, --yes", "Skip confirmation", false)
109
143
  .action(async (strategyId: string, options: { dir?: string; date?: string; yes?: boolean }) => {
144
+ const startMs = Date.now();
110
145
  const result = await forkStrategy(config, strategyId, {
111
146
  targetDir: options.dir,
112
147
  dateDir: options.date,
@@ -114,6 +149,7 @@ export function registerStrategyCli(params: {
114
149
  });
115
150
 
116
151
  if (result.success) {
152
+ logCli(db, "fork", { strategyId }, startMs);
117
153
  console.log("✓ 策略 Fork 成功!");
118
154
  console.log("");
119
155
  console.log(` 名称: ${result.sourceName}`);
@@ -124,6 +160,7 @@ export function registerStrategyCli(params: {
124
160
  console.log(` 验证: openfinclaw strategy validate ${result.localPath}`);
125
161
  console.log(` 发布: openfinclaw strategy publish ${result.localPath}`);
126
162
  } else {
163
+ logCli(db, "fork", { strategyId }, startMs, result.error ?? "unknown");
127
164
  console.error(`✗ Fork 失败: ${result.error}`);
128
165
  process.exitCode = 1;
129
166
  }
@@ -135,6 +172,7 @@ export function registerStrategyCli(params: {
135
172
  .description("List all local strategies")
136
173
  .option("--json", "Output as JSON", false)
137
174
  .action(async (options: { json?: boolean }) => {
175
+ const startMs = Date.now();
138
176
  const strategies = await listLocalStrategies();
139
177
 
140
178
  if (options.json) {
@@ -164,6 +202,7 @@ export function registerStrategyCli(params: {
164
202
  s.displayName.length > 20 ? s.displayName.slice(0, 17) + "..." : s.displayName;
165
203
  console.log(` ${name.padEnd(40)} ${displayName.padEnd(20)} ${typeLabel}`);
166
204
  }
205
+ logCli(db, "list", { count: strategies.length }, startMs);
167
206
  });
168
207
 
169
208
  // ── strategy show ──
@@ -173,9 +212,11 @@ export function registerStrategyCli(params: {
173
212
  .option("--remote", "Fetch latest info from Hub", false)
174
213
  .option("--json", "Output as JSON", false)
175
214
  .action(async (nameOrId: string, options: { remote?: boolean; json?: boolean }) => {
215
+ const startMs = Date.now();
176
216
  const local = await findLocalStrategy(nameOrId);
177
217
 
178
218
  if (!local && !options.remote) {
219
+ logCli(db, "show", { nameOrId }, startMs, "not found");
179
220
  console.error(`✗ 本地策略未找到: ${nameOrId}`);
180
221
  console.error(" 使用 --remote 从 Hub 获取信息");
181
222
  process.exitCode = 1;
@@ -186,6 +227,7 @@ export function registerStrategyCli(params: {
186
227
  const infoResult = await fetchStrategyInfo(config, local.sourceId);
187
228
  if (infoResult.success && infoResult.data) {
188
229
  const info = infoResult.data;
230
+ logCli(db, "show", { nameOrId, remote: true }, startMs);
189
231
  if (options.json) {
190
232
  console.log(JSON.stringify({ local, hub: info }, null, 2));
191
233
  return;
@@ -196,6 +238,7 @@ export function registerStrategyCli(params: {
196
238
  }
197
239
 
198
240
  if (local) {
241
+ logCli(db, "show", { nameOrId }, startMs);
199
242
  if (options.json) {
200
243
  console.log(JSON.stringify(local, null, 2));
201
244
  return;
@@ -204,6 +247,7 @@ export function registerStrategyCli(params: {
204
247
  return;
205
248
  }
206
249
 
250
+ logCli(db, "show", { nameOrId }, startMs, "not found");
207
251
  console.error(`✗ 策略未找到: ${nameOrId}`);
208
252
  process.exitCode = 1;
209
253
  });
@@ -215,8 +259,10 @@ export function registerStrategyCli(params: {
215
259
  .description("Remove a local strategy")
216
260
  .option("-f, --force", "Force removal without confirmation", false)
217
261
  .action(async (nameOrId: string, options: { force?: boolean }) => {
262
+ const startMs = Date.now();
218
263
  const local = await findLocalStrategy(nameOrId);
219
264
  if (!local) {
265
+ logCli(db, "remove", { nameOrId }, startMs, "not found");
220
266
  console.error(`✗ 策略未找到: ${nameOrId}`);
221
267
  process.exitCode = 1;
222
268
  return;
@@ -232,8 +278,10 @@ export function registerStrategyCli(params: {
232
278
 
233
279
  const result = await removeLocalStrategy(nameOrId);
234
280
  if (result.success) {
281
+ logCli(db, "remove", { nameOrId }, startMs);
235
282
  console.log("✓ 策略已删除");
236
283
  } else {
284
+ logCli(db, "remove", { nameOrId }, startMs, result.error ?? "unknown");
237
285
  console.error(`✗ 删除失败: ${result.error}`);
238
286
  process.exitCode = 1;
239
287
  }
package/src/config.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Unified configuration resolver for OpenFinClaw plugin.
3
3
  * Supports single API key for both Hub and DataHub services.
4
4
  */
5
- import type { OpenClawPluginApi } from "openfinclaw/plugin-sdk";
5
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
6
6
  import type { UnifiedPluginConfig } from "./types.js";
7
7
 
8
8
  const DEFAULT_HUB_API_URL = "https://hub.openfinclaw.ai";
@@ -4,7 +4,7 @@ import type { DatabaseSync } from "node:sqlite";
4
4
  * Tools: fin_price, fin_kline, fin_crypto, fin_compare, fin_slim_search
5
5
  */
6
6
  import { Type } from "@sinclair/typebox";
7
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
7
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
8
8
  import { withLogging } from "../middleware/with-logging.js";
9
9
  import type { UnifiedPluginConfig, MarketType } from "../types.js";
10
10
  import { DataHubClient, guessMarket } from "./client.js";
@@ -6,7 +6,7 @@ import { randomUUID } from "node:crypto";
6
6
  import { readFile } from "node:fs/promises";
7
7
  import type { DatabaseSync } from "node:sqlite";
8
8
  import { Type } from "@sinclair/typebox";
9
- import type { OpenClawPluginApi } from "openfinclaw/plugin-sdk";
9
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
10
10
  import {
11
11
  insertAgentEvent,
12
12
  insertBacktestResult,
@@ -1,301 +0,0 @@
1
- ---
2
- name: openfinclaw
3
- description: "OpenFinClaw 入口 - 统一金融工具平台。行情数据(价格/K线/加密市场/多资产对比)、策略工具(创建/验证/发布/Fork)。当用户提到 FinClaw、Hub、策略、行情、价格、K线、加密货币、BTC、ETH、DeFi 时触发。"
4
- metadata:
5
- openclaw:
6
- emoji: "🦈"
7
- requires:
8
- extensions: ["openfinclaw"]
9
- ---
10
-
11
- # OpenFinClaw
12
-
13
- 统一金融工具平台,一个 API Key 即可使用所有功能:
14
-
15
- - **行情数据**: 价格查询、K线、加密市场数据、多资产对比、代码搜索
16
- - **策略工具**: 创建、验证、发布、Fork 策略
17
- - **统一认证**: 一个 API Key 访问 Hub 和 DataHub
18
-
19
- ## 平台简介
20
-
21
- **Hub 平台 (hub.openfinclaw.ai)** 是一个 7×24 小时全球策略进化网络:
22
-
23
- - **策略分享**: 发布你的策略,供社区成员查看和 Fork
24
- - **回测验证**: 发布时自动运行回测,验证策略有效性
25
- - **社区进化**: 其他用户可以 Fork 你的策略进行优化改进
26
- - **绩效排行**: 查看各市场表现最佳的策略
27
-
28
- **DataHub** 提供实时行情数据:
29
-
30
- - **多市场覆盖**: 加密货币、A股、港股、美股
31
- - **丰富数据**: 价格、K线、OHLCV、DeFi TVL、资金费率
32
- - **数据来源**: CoinGecko、DefiLlama、CCXT、Tushare
33
-
34
- 核心价值:**不要追逐浪潮,创造浪潮。**
35
-
36
- ## 快速开始
37
-
38
- ### 行情查询(需要 API Key)
39
-
40
- ```
41
- 用户: BTC 现在多少钱
42
- Agent: 使用 fin_price 获取实时价格
43
-
44
- 用户: ETH 最近 7 天走势
45
- Agent: 使用 fin_kline 获取 K 线数据
46
-
47
- 用户: DeFi 哪个协议 TVL 最高
48
- Agent: 使用 fin_crypto 获取 DeFi 排名
49
-
50
- 用户: BTC 和 ETH 谁涨得多
51
- Agent: 使用 fin_compare 对比收益
52
- ```
53
-
54
- ### 策略管理
55
-
56
- ```bash
57
- # 查看排行榜(无需 API Key)
58
- openclaw strategy leaderboard
59
-
60
- # 查看收益榜 Top 10
61
- openclaw strategy leaderboard returns --limit 10
62
-
63
- # 查看策略详情(无需 API Key)
64
- openclaw strategy show 550e8400-e29b-41d4-a716-446655440001 --remote
65
- ```
66
-
67
- ## 安装指南
68
-
69
- ### 前置检查
70
-
71
- 在安装前,检查用户是否已安装 OpenClaw:
72
-
73
- ```bash
74
- openclaw --version
75
- ```
76
-
77
- 如果未安装,引导用户安装 OpenClaw(参考 https://docs.openclaw.ai/install)。
78
-
79
- ### 安装 openfinclaw 插件
80
-
81
- ```bash
82
- openclaw plugins install @openfinclaw/openfinclaw-strategy
83
- openclaw plugins enable @openfinclaw/openfinclaw-strategy
84
- ```
85
-
86
- ### 验证安装
87
-
88
- ```bash
89
- # 查看插件状态
90
- openclaw plugins list
91
-
92
- # 测试命令
93
- openclaw strategy list
94
- ```
95
-
96
- ### 配置 API Key
97
-
98
- 从 https://hub.openfinclaw.ai 获取 API Key(以 `fch_` 开头),**一个 Key 即可使用所有功能**:
99
-
100
- ```bash
101
- openclaw config set plugins.entries.openfinclaw.config.apiKey YOUR_API_KEY
102
- ```
103
-
104
- 或使用环境变量:
105
-
106
- ```bash
107
- export OPENFINCLAW_API_KEY=YOUR_API_KEY
108
- ```
109
-
110
- ### ⚠️ API Key 安全提醒
111
-
112
- **重要:请勿泄露你的 API Key!**
113
-
114
- - API Key 以 `fch_` 开头,用于 Hub 和 DataHub 接口校验
115
- - **不要**将 API Key 提交到 Git 仓库或公开分享
116
- - **不要**在公开聊天、截图、代码示例中暴露真实的 API Key
117
- - 如果怀疑 Key 已泄露,请立即在 Hub 个人设置中重新生成
118
-
119
- ## 功能概览
120
-
121
- 本插件提供两大类能力:
122
-
123
- ### 行情数据工具
124
-
125
- | 工具名 | 用途 | 需要 API Key |
126
- | ----------------- | --------------------------- | ------------ |
127
- | `fin_price` | 价格查询(股票/加密/指数) | **是** |
128
- | `fin_kline` | K线/OHLCV 数据 | **是** |
129
- | `fin_crypto` | 加密市场数据(21个端点) | **是** |
130
- | `fin_compare` | 多资产价格对比(2-5个资产) | **是** |
131
- | `fin_slim_search` | 代码/名称搜索 | **是** |
132
-
133
- ### 策略工具
134
-
135
- | 工具名 | 用途 | 需要 API Key |
136
- | ---------------------- | -------------------------------------- | ------------ |
137
- | `skill_leaderboard` | 查询排行榜(综合/收益/风控/人气/新星) | 否 |
138
- | `skill_get_info` | 获取 Hub 策略公开详情 | 否 |
139
- | `skill_validate` | 本地验证策略包格式(FEP v2.0) | 否 |
140
- | `skill_list_local` | 列出本地已下载的策略 | 否 |
141
- | `skill_fork` | 从 Hub 下载公开策略到本地 | **是** |
142
- | `skill_publish` | 发布策略 ZIP 到 Hub,自动触发回测 | **是** |
143
- | `skill_publish_verify` | 查询发布状态和回测报告 | **是** |
144
-
145
- ### Skills(指导文档)
146
-
147
- #### 行情数据 Skills
148
-
149
- | Skill | 触发场景 | 说明 |
150
- | ------------- | ------------------ | ---------------- |
151
- | `price-check` | 快速查价、XX多少钱 | 最简单的价格查询 |
152
-
153
- #### 策略 Skills
154
-
155
- | Skill | 触发场景 | 说明 |
156
- | ------------------ | ------------------------ | ----------------------------- |
157
- | `strategy-builder` | 创建新策略、生成策略代码 | 自然语言 → FEP v2.0 策略包 |
158
- | `skill-publish` | 发布策略到服务器 | 验证 → 打包 → 发布 → 查询回测 |
159
- | `strategy-fork` | 下载/克隆 Hub 策略 | Fork → 本地编辑 → 发布新版本 |
160
- | `strategy-pack` | 创建回测策略包 | 生成 fep.yaml + strategy.py |
161
-
162
- ### 典型工作流
163
-
164
- ```
165
- 行情查询 → 分析决策 → 策略创建 → 验证 → 发布 → Fork → 优化
166
- ↓ ↓ ↓ ↓ ↓
167
- fin_price compare strategy-builder skill_validate skill_publish
168
- fin_kline skill_fork skill_publish_verify
169
- ```
170
-
171
- ## CLI 命令
172
-
173
- ### strategy leaderboard
174
-
175
- 查看 Hub 排行榜(无需 API Key):
176
-
177
- ```bash
178
- # 综合榜 Top 20(默认)
179
- openclaw strategy leaderboard
180
-
181
- # 收益榜 Top 10
182
- openclaw strategy leaderboard returns --limit 10
183
-
184
- # 人气榜第 21-40 名
185
- openclaw strategy leaderboard popular --offset 20 --limit 20
186
- ```
187
-
188
- **榜单类型**:
189
-
190
- | 榜单类型 | 说明 | 排序依据 |
191
- | ----------- | -------------- | ---------------- |
192
- | `composite` | 综合榜(默认) | FCS 综合分 |
193
- | `returns` | 收益榜 | 收益率 |
194
- | `risk` | 风控榜 | 风控分 |
195
- | `popular` | 人气榜 | 订阅数 |
196
- | `rising` | 新星榜 | 30天内新策略收益 |
197
-
198
- ### strategy fork
199
-
200
- 从 Hub 下载策略到本地:
201
-
202
- ```bash
203
- # 使用策略 ID
204
- openclaw strategy fork 34a5792f-7d20-4a15-90f3-26f1c54fa4a6
205
-
206
- # 使用 Hub URL
207
- openclaw strategy fork https://hub.openfinclaw.ai/strategy/34a5792f-7d20-4a15-90f3-26f1c54fa4a6
208
- ```
209
-
210
- ### strategy list
211
-
212
- 列出本地策略:
213
-
214
- ```bash
215
- openclaw strategy list
216
- ```
217
-
218
- ### strategy show
219
-
220
- 查看策略详情:
221
-
222
- ```bash
223
- # 查看本地策略
224
- openclaw strategy show btc-adaptive-dca-34a5792f
225
-
226
- # 从 Hub 获取最新信息(无需 API Key)
227
- openclaw strategy show 550e8400-e29b-41d4-a716-446655440001 --remote
228
- ```
229
-
230
- ## 本地存储结构
231
-
232
- 策略存储在 `~/.openfinclaw/workspace/strategies/` 目录:
233
-
234
- ```
235
- ~/.openfinclaw/workspace/strategies/
236
- └── 2026-03-16/ # 按日期组织
237
- ├── btc-adaptive-dca-34a5792f/ # 名称 + 短ID(Fork 来的)
238
- │ ├── fep.yaml # 策略配置
239
- │ ├── scripts/
240
- │ │ └── strategy.py # 策略代码
241
- │ └── .fork-meta.json # 元数据
242
- └── my-new-strategy/ # 自建策略(无短ID)
243
- └── ...
244
- ```
245
-
246
- ## 触发场景与相关 Skills
247
-
248
- 当用户提到以下内容时,应引导阅读对应的 Skill:
249
-
250
- | 触发关键词 | Skill | 说明 |
251
- | ------------------------------ | ------------------ | ------------------- |
252
- | XX多少钱、什么价格、查价 | `price-check` | 最简单的价格查询 |
253
- | 创建策略、写策略、生成策略包 | `strategy-builder` | 自然语言 → FEP v2.0 |
254
- | 发布策略、上传策略、提交策略 | `skill-publish` | 验证 → 打包 → 发布 |
255
- | Fork 策略、下载策略、克隆策略 | `strategy-fork` | 从 Hub Fork 策略 |
256
- | 策略包格式、FEP 规范、打包回测 | `strategy-pack` | FEP v2.0 规范详解 |
257
-
258
- ## 配置选项
259
-
260
- | 配置项 | 环境变量 | 说明 | 默认值 |
261
- | ------------------- | --------------------- | ---------------- | ---------------------------- |
262
- | `apiKey` | `OPENFINCLAW_API_KEY` | 统一 API Key | 必填 |
263
- | `hubApiUrl` | `HUB_API_URL` | Hub 服务地址 | `https://hub.openfinclaw.ai` |
264
- | `datahubGatewayUrl` | `DATAHUB_GATEWAY_URL` | DataHub 网关地址 | `http://43.134.61.136:9080` |
265
- | `requestTimeoutMs` | `REQUEST_TIMEOUT_MS` | 请求超时(毫秒) | `60000` |
266
-
267
- ## 常见问题
268
-
269
- ### Q: API Key 在哪里获取?
270
-
271
- 访问 https://hub.openfinclaw.ai 登录后在个人设置中获取。**一个 Key 即可使用所有功能**。
272
-
273
- ### Q: 行情数据需要额外付费吗?
274
-
275
- API Key 已包含行情数据访问权限,无需额外付费。
276
-
277
- ### Q: Fork 的策略可以修改吗?
278
-
279
- 可以。Fork 下载到本地后,可以自由修改 `scripts/strategy.py`,然后发布为自己的新版本。
280
-
281
- ### Q: 发布策略会公开吗?
282
-
283
- 取决于 `fep.yaml` 中的 `identity.visibility` 设置:
284
-
285
- - `public`: 公开,社区可见可 Fork
286
- - `private`: 私有,仅自己可见
287
- - `unlisted`: 不公开但可通过链接访问
288
-
289
- ### Q: 如何检查 openfinclaw 是否已安装?
290
-
291
- ```bash
292
- openclaw plugins list | grep openfinclaw
293
- ```
294
-
295
- ## 链接
296
-
297
- - **Hub 平台**: https://hub.openfinclaw.ai
298
- - **排行榜**: https://hub.openfinclaw.ai/leaderboard
299
- - **策略发现**: https://hub.openfinclaw.ai/discover
300
- - **获取 API Key**: https://hub.openfinclaw.ai/dashboard
301
- - **GitHub 仓库**: https://github.com/cryptoSUN2049/openFinclaw