desic-okx-agent 0.3.1 → 0.3.3
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.en.md +1 -1
- package/README.md +1 -1
- package/dist/i18n/messages.d.ts +27 -0
- package/dist/i18n/messages.js +55 -1
- package/dist/i18n/messages.js.map +1 -1
- package/dist/report/brand-font.d.ts +1 -0
- package/dist/report/brand-font.js +4 -0
- package/dist/report/brand-font.js.map +1 -0
- package/dist/report/chart-script.d.ts +3 -8
- package/dist/report/chart-script.js +735 -115
- package/dist/report/chart-script.js.map +1 -1
- package/dist/report/compare-html.d.ts +1 -6
- package/dist/report/compare-html.js +177 -122
- package/dist/report/compare-html.js.map +1 -1
- package/dist/report/compare-script.d.ts +1 -11
- package/dist/report/compare-script.js +310 -64
- package/dist/report/compare-script.js.map +1 -1
- package/dist/report/fetch.d.ts +32 -0
- package/dist/report/fetch.js +42 -0
- package/dist/report/fetch.js.map +1 -1
- package/dist/report/html.d.ts +1 -1
- package/dist/report/html.js +846 -268
- package/dist/report/html.js.map +1 -1
- package/dist/strategy/service.js +4 -1
- package/dist/strategy/service.js.map +1 -1
- package/dist/strategy/store.d.ts +12 -1
- package/dist/strategy/store.js +32 -1
- package/dist/strategy/store.js.map +1 -1
- package/dist/tools/catalog.js +20 -1
- package/dist/tools/catalog.js.map +1 -1
- package/dist/tui/app.js +106 -35
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/commands.d.ts +33 -0
- package/dist/tui/commands.js +59 -14
- package/dist/tui/commands.js.map +1 -1
- package/dist/tui/file-completion.d.ts +13 -0
- package/dist/tui/file-completion.js +57 -0
- package/dist/tui/file-completion.js.map +1 -0
- package/docs/strategy-research.md +16 -3
- package/package.json +1 -1
- package/python/desic_strategy/context.py +23 -5
- package/python/desic_strategy/engine.py +4 -1
- package/python/desic_strategy/live.py +1 -1
- package/python/desic_strategy/policy.py +51 -0
- package/python/desic_strategy/runner.py +36 -9
- package/python/desic_strategy/timeframe.py +17 -0
- package/skills/okx-strategy-research/SKILL.md +55 -1
- package/skills/okx-strategy-research/agents/openai.yaml +1 -1
- package/skills/okx-strategy-research/references/python-api.md +7 -0
- package/skills/okx-strategy-research/references/tools-and-data.md +20 -0
package/dist/tui/commands.js
CHANGED
|
@@ -39,7 +39,7 @@ export const COMMANDS = [
|
|
|
39
39
|
name: "help",
|
|
40
40
|
summary: "cmdHelp",
|
|
41
41
|
usage: "/help [command]",
|
|
42
|
-
args: [{ name: "command", description: "argHelpCommand", required: false }]
|
|
42
|
+
args: [{ name: "command", description: "argHelpCommand", required: false, completes: "command" }]
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
name: "data",
|
|
@@ -53,7 +53,7 @@ export const COMMANDS = [
|
|
|
53
53
|
usage: "/download <instrument> [days | range]",
|
|
54
54
|
detail: "cmdDownloadDetail",
|
|
55
55
|
args: [
|
|
56
|
-
{ name: "instrument", description: "argInstrument", default: "BTC-USDT-SWAP" },
|
|
56
|
+
{ name: "instrument", description: "argInstrument", default: "BTC-USDT-SWAP", completes: "instrument" },
|
|
57
57
|
{ name: "days | range", description: "argWindow30", default: "30" }
|
|
58
58
|
]
|
|
59
59
|
},
|
|
@@ -72,7 +72,7 @@ export const COMMANDS = [
|
|
|
72
72
|
summary: "cmdValidate",
|
|
73
73
|
usage: "/validate <file.py>",
|
|
74
74
|
detail: "cmdValidateDetail",
|
|
75
|
-
args: [{ name: "file.py", description: "argStrategyToCheck", required: true }]
|
|
75
|
+
args: [{ name: "file.py", description: "argStrategyToCheck", required: true, completes: "strategy-file" }]
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
name: "backtest",
|
|
@@ -80,8 +80,8 @@ export const COMMANDS = [
|
|
|
80
80
|
usage: "/backtest <file.py | setting> [instrument] [days | range]",
|
|
81
81
|
detail: "cmdBacktestDetail",
|
|
82
82
|
args: [
|
|
83
|
-
{ name: "file.py | setting", description: "argStrategyOrSetting", required: true },
|
|
84
|
-
{ name: "instrument", description: "argInstrument", default: "BTC-USDT-SWAP" },
|
|
83
|
+
{ name: "file.py | setting", description: "argStrategyOrSetting", required: true, completes: "strategy-file" },
|
|
84
|
+
{ name: "instrument", description: "argInstrument", default: "BTC-USDT-SWAP", completes: "instrument" },
|
|
85
85
|
{ name: "days | range", description: "argWindow30", default: "30" }
|
|
86
86
|
]
|
|
87
87
|
},
|
|
@@ -91,8 +91,8 @@ export const COMMANDS = [
|
|
|
91
91
|
usage: "/optimize <file.py | report> [instrument] [days | range] [space.json] [budget]",
|
|
92
92
|
detail: "cmdOptimizeDetail",
|
|
93
93
|
args: [
|
|
94
|
-
{ name: "file.py | report", description: "argStrategyOrReport", required: true },
|
|
95
|
-
{ name: "instrument", description: "argInstrument", default: "BTC-USDT-SWAP" },
|
|
94
|
+
{ name: "file.py | report", description: "argStrategyOrReport", required: true, completes: "strategy-file" },
|
|
95
|
+
{ name: "instrument", description: "argInstrument", default: "BTC-USDT-SWAP", completes: "instrument" },
|
|
96
96
|
{ name: "days | range", description: "argWindow90", default: "90" },
|
|
97
97
|
{ name: "space.json", description: "argSpaceFile", default: "space.json" },
|
|
98
98
|
{ name: "budget", description: "argBudget", default: "100" }
|
|
@@ -104,7 +104,7 @@ export const COMMANDS = [
|
|
|
104
104
|
usage: "/compare <runId> <runId> [runId...] [--no-open]",
|
|
105
105
|
detail: "cmdCompareDetail",
|
|
106
106
|
args: [
|
|
107
|
-
{ name: "runId runId ...", description: "argRunsToCompare", required: true },
|
|
107
|
+
{ name: "runId runId ...", description: "argRunsToCompare", required: true, completes: "run" },
|
|
108
108
|
{ name: "--no-open", description: "argNoOpen", required: false }
|
|
109
109
|
]
|
|
110
110
|
},
|
|
@@ -123,7 +123,7 @@ export const COMMANDS = [
|
|
|
123
123
|
summary: "cmdMarket",
|
|
124
124
|
usage: "/market [demo|live]",
|
|
125
125
|
detail: "cmdMarketDetail",
|
|
126
|
-
args: [{ name: "demo | live", description: "argMarketEnv", required: false }]
|
|
126
|
+
args: [{ name: "demo | live", description: "argMarketEnv", required: false, completes: "market-environment" }]
|
|
127
127
|
},
|
|
128
128
|
{
|
|
129
129
|
name: "settings",
|
|
@@ -135,14 +135,14 @@ export const COMMANDS = [
|
|
|
135
135
|
name: "coverage",
|
|
136
136
|
summary: "cmdCoverage",
|
|
137
137
|
usage: "/coverage <instrument>",
|
|
138
|
-
args: [{ name: "instrument", description: "argInstrument", default: "BTC-USDT-SWAP" }],
|
|
138
|
+
args: [{ name: "instrument", description: "argInstrument", default: "BTC-USDT-SWAP", completes: "instrument" }],
|
|
139
139
|
detail: "cmdCoverageDetail"
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
142
|
name: "delete",
|
|
143
143
|
summary: "cmdDelete",
|
|
144
144
|
usage: "/delete <runId>",
|
|
145
|
-
args: [{ name: "runId", description: "argRunToDelete", required: true }],
|
|
145
|
+
args: [{ name: "runId", description: "argRunToDelete", required: true, completes: "run" }],
|
|
146
146
|
detail: "cmdDeleteDetail"
|
|
147
147
|
},
|
|
148
148
|
{
|
|
@@ -156,7 +156,7 @@ export const COMMANDS = [
|
|
|
156
156
|
summary: "cmdReport",
|
|
157
157
|
usage: "/report <runId>",
|
|
158
158
|
args: [
|
|
159
|
-
{ name: "runId", description: "argRunToOpen", required: true },
|
|
159
|
+
{ name: "runId", description: "argRunToOpen", required: true, completes: "run" },
|
|
160
160
|
{ name: "--no-open", description: "argNoOpen", required: false }
|
|
161
161
|
]
|
|
162
162
|
},
|
|
@@ -164,7 +164,7 @@ export const COMMANDS = [
|
|
|
164
164
|
name: "cancel",
|
|
165
165
|
summary: "cmdCancel",
|
|
166
166
|
usage: "/cancel <runId>",
|
|
167
|
-
args: [{ name: "runId", description: "argRunToCancel", required: true }]
|
|
167
|
+
args: [{ name: "runId", description: "argRunToCancel", required: true, completes: "run" }]
|
|
168
168
|
},
|
|
169
169
|
{
|
|
170
170
|
name: "env",
|
|
@@ -182,7 +182,7 @@ export const COMMANDS = [
|
|
|
182
182
|
summary: "cmdLang",
|
|
183
183
|
usage: "/lang [en|zh]",
|
|
184
184
|
detail: "cmdLangDetail",
|
|
185
|
-
args: [{ name: "locale", description: "argLocale", required: false }]
|
|
185
|
+
args: [{ name: "locale", description: "argLocale", required: false, completes: "locale" }]
|
|
186
186
|
},
|
|
187
187
|
{
|
|
188
188
|
name: "clear",
|
|
@@ -267,6 +267,51 @@ export function argumentIndex(input) {
|
|
|
267
267
|
return -1;
|
|
268
268
|
return /\s$/.test(input) ? parts.length - 1 : parts.length - 2;
|
|
269
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Whether the argument being typed has a completable value, and what to match on.
|
|
272
|
+
*
|
|
273
|
+
* Returns the request rather than the candidates: the shell holds the runtime client
|
|
274
|
+
* and this stays a pure function of the input, testable without a terminal or a
|
|
275
|
+
* running runtime.
|
|
276
|
+
*/
|
|
277
|
+
export function valueCompletion(input) {
|
|
278
|
+
const parsed = parseCommand(input);
|
|
279
|
+
if (!parsed?.known)
|
|
280
|
+
return null;
|
|
281
|
+
const spec = commandByName(parsed.name);
|
|
282
|
+
if (!spec?.args?.length)
|
|
283
|
+
return null;
|
|
284
|
+
if (!/\s/.test(input))
|
|
285
|
+
return null;
|
|
286
|
+
const active = argumentIndex(input);
|
|
287
|
+
const argument = active >= 0 ? spec.args[active] : undefined;
|
|
288
|
+
// A trailing space means this argument has not been started, so everything matches.
|
|
289
|
+
const started = !/\s$/.test(input);
|
|
290
|
+
const prefix = started ? (parsed.args[active] ?? "") : "";
|
|
291
|
+
const head = started ? input.slice(0, input.length - prefix.length) : input;
|
|
292
|
+
const source = parsed.name === "compare" && active >= 0 && !prefix.startsWith("-")
|
|
293
|
+
? "run"
|
|
294
|
+
: parsed.name === "optimize" &&
|
|
295
|
+
active === 1 &&
|
|
296
|
+
parsed.args[0]?.toLowerCase() === "report" &&
|
|
297
|
+
!prefix.startsWith("-")
|
|
298
|
+
? "run"
|
|
299
|
+
: argument?.completes;
|
|
300
|
+
return source ? { source, prefix, head } : null;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Narrows candidate values to those matching a partial argument.
|
|
304
|
+
*
|
|
305
|
+
* Case-insensitive and anchored: typing `BT` offers `BTC-USDT-SWAP`, and matching
|
|
306
|
+
* anywhere in the name would put `ETH-BTC-SWAP` above it for no reason a user typing
|
|
307
|
+
* a prefix would expect.
|
|
308
|
+
*/
|
|
309
|
+
export function matchValues(candidates, prefix) {
|
|
310
|
+
if (!prefix)
|
|
311
|
+
return [...candidates];
|
|
312
|
+
const lower = prefix.toLowerCase();
|
|
313
|
+
return candidates.filter((candidate) => candidate.toLowerCase().startsWith(lower));
|
|
314
|
+
}
|
|
270
315
|
/**
|
|
271
316
|
* Inline hint for a recognized command.
|
|
272
317
|
*
|
package/dist/tui/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/tui/commands.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/tui/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface FileDiscoveryOptions {
|
|
2
|
+
maxDepth?: number;
|
|
3
|
+
maxDirectories?: number;
|
|
4
|
+
maxFiles?: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Finds strategy-shaped Python files below a working directory.
|
|
8
|
+
*
|
|
9
|
+
* The walk is deliberately bounded and does not follow symlinks. Completion runs
|
|
10
|
+
* while the user is typing, so a large checkout or a symlink cycle must not turn a
|
|
11
|
+
* convenience into an unbounded filesystem crawl.
|
|
12
|
+
*/
|
|
13
|
+
export declare function discoverPythonFiles(root?: string, options?: FileDiscoveryOptions): Promise<string[]>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const IGNORED_DIRECTORIES = new Set([
|
|
4
|
+
".git",
|
|
5
|
+
".hg",
|
|
6
|
+
".svn",
|
|
7
|
+
".tox",
|
|
8
|
+
".venv",
|
|
9
|
+
"__pycache__",
|
|
10
|
+
"build",
|
|
11
|
+
"dist",
|
|
12
|
+
"node_modules",
|
|
13
|
+
"target",
|
|
14
|
+
"venv"
|
|
15
|
+
]);
|
|
16
|
+
/**
|
|
17
|
+
* Finds strategy-shaped Python files below a working directory.
|
|
18
|
+
*
|
|
19
|
+
* The walk is deliberately bounded and does not follow symlinks. Completion runs
|
|
20
|
+
* while the user is typing, so a large checkout or a symlink cycle must not turn a
|
|
21
|
+
* convenience into an unbounded filesystem crawl.
|
|
22
|
+
*/
|
|
23
|
+
export async function discoverPythonFiles(root = process.cwd(), options = {}) {
|
|
24
|
+
const maxDepth = options.maxDepth ?? 5;
|
|
25
|
+
const maxDirectories = options.maxDirectories ?? 500;
|
|
26
|
+
const maxFiles = options.maxFiles ?? 500;
|
|
27
|
+
const pending = [{ absolute: path.resolve(root), depth: 0 }];
|
|
28
|
+
const files = [];
|
|
29
|
+
let visitedDirectories = 0;
|
|
30
|
+
while (pending.length > 0 && visitedDirectories < maxDirectories && files.length < maxFiles) {
|
|
31
|
+
const current = pending.shift();
|
|
32
|
+
visitedDirectories += 1;
|
|
33
|
+
const entries = await readdir(current.absolute, { withFileTypes: true }).catch(() => []);
|
|
34
|
+
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
if (files.length >= maxFiles)
|
|
37
|
+
break;
|
|
38
|
+
if (entry.isSymbolicLink())
|
|
39
|
+
continue;
|
|
40
|
+
const absolute = path.join(current.absolute, entry.name);
|
|
41
|
+
if (entry.isDirectory()) {
|
|
42
|
+
if (current.depth >= maxDepth || entry.name.startsWith(".") || IGNORED_DIRECTORIES.has(entry.name))
|
|
43
|
+
continue;
|
|
44
|
+
pending.push({ absolute, depth: current.depth + 1 });
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (!entry.isFile() || !entry.name.toLowerCase().endsWith(".py"))
|
|
48
|
+
continue;
|
|
49
|
+
const relative = path.relative(root, absolute).split(path.sep).join("/");
|
|
50
|
+
// The TUI parser is whitespace-delimited and does not yet implement quoting.
|
|
51
|
+
if (relative && !/\s/.test(relative))
|
|
52
|
+
files.push(relative);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return files.sort((left, right) => left.localeCompare(right));
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=file-completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-completion.js","sourceRoot":"","sources":["../../src/tui/file-completion.ts"],"names":[],"mappings":"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"}
|
|
@@ -199,9 +199,7 @@ desic-okx strategy validate --file ema.py
|
|
|
199
199
|
|
|
200
200
|
### 多周期
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
desic-okx strategy backtest --file s.py --inst BTC-USDT-SWAP --intervals 30m,1H
|
|
204
|
-
```
|
|
202
|
+
**直接写就行,不需要声明。** 引擎会读你的源码,把 `ctx.market.bars(..., "30m")` 里出现的周期自动加进来:
|
|
205
203
|
|
|
206
204
|
```python
|
|
207
205
|
buckets = ctx.market.bars(ctx.instrument_id, "30m", lookback=2)
|
|
@@ -209,6 +207,19 @@ if not buckets[-1].confirmed:
|
|
|
209
207
|
return ctx.no_action("等 30m 收线")
|
|
210
208
|
```
|
|
211
209
|
|
|
210
|
+
```bash
|
|
211
|
+
desic-okx strategy backtest --file s.py --inst BTC-USDT-SWAP # 30m 自动派生
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
报告的 `assumptions.intervals` 记录的是**实际派生的**那些,不是你请求的 —— 所以你能核对引擎理解得对不对。
|
|
215
|
+
|
|
216
|
+
`--intervals` 仍然保留,用于**周期名是算出来的**情况 —— 那种源码里读不出来:
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
chosen = ctx.params.get("tf", "15m") # 读不出来
|
|
220
|
+
ctx.market.bars(ctx.instrument_id, chosen) # 需要 --intervals 15m
|
|
221
|
+
```
|
|
222
|
+
|
|
212
223
|
注意:`ctx.indicators` 只接受 `1m`。高周期的当前桶在确认前还可能被修正,用它做增量指标状态,缓存值会悄悄依赖于"第一次算的时间点"。
|
|
213
224
|
|
|
214
225
|
### 只要尾部就一定传 `lookback`
|
|
@@ -520,6 +531,8 @@ MCP 工具(`desic-okx setup` 会自动为 Codex 和 Claude Code 装好):
|
|
|
520
531
|
| `strategy_run_optimize` | 参数搜索,入队 |
|
|
521
532
|
| `strategy_get_optimization` | 排名后的候选表,含训练/验证指标 |
|
|
522
533
|
| `strategy_compare_runs` | 多运行对比,含差异参数与警告 |
|
|
534
|
+
| `strategy_open_report` | 生成单次运行的 HTML 报告并在浏览器打开 |
|
|
535
|
+
| `strategy_open_comparison` | 同上,多运行对比,叠加权益曲线 |
|
|
523
536
|
| `strategy_get_run` | 状态、进度、汇总指标 |
|
|
524
537
|
| `strategy_get_run_equity` / `_trades` / `_actions` | 分页读明细 |
|
|
525
538
|
| `strategy_settings` / `_update` | 读写回测参数 |
|
package/package.json
CHANGED
|
@@ -24,19 +24,24 @@ class ContextError(Exception):
|
|
|
24
24
|
class MarketView:
|
|
25
25
|
"""Point-in-time K-line access across derived timeframes."""
|
|
26
26
|
|
|
27
|
-
__slots__ = ("_aggregates", "_instrument_id", "_minutes", "_visible")
|
|
27
|
+
__slots__ = ("_aggregates", "_aggregators", "_instrument_id", "_minutes", "_visible")
|
|
28
28
|
|
|
29
29
|
def __init__(
|
|
30
30
|
self,
|
|
31
31
|
instrument_id: str,
|
|
32
32
|
minutes: list[Bar],
|
|
33
33
|
visible: int,
|
|
34
|
-
aggregates: Mapping[str, tuple[Bar, ...]],
|
|
34
|
+
aggregates: Mapping[str, tuple[Bar, ...]] | None = None,
|
|
35
|
+
aggregators: Mapping[str, TimeframeAggregator] | None = None,
|
|
35
36
|
) -> None:
|
|
36
37
|
self._instrument_id = instrument_id
|
|
37
38
|
self._minutes = minutes
|
|
38
39
|
self._visible = visible
|
|
39
|
-
|
|
40
|
+
# Either form works. `aggregators` applies a lookback before the tuple is built,
|
|
41
|
+
# which is the cheap path; `aggregates` keeps a caller that already holds
|
|
42
|
+
# snapshots working unchanged.
|
|
43
|
+
self._aggregates = aggregates or {}
|
|
44
|
+
self._aggregators = aggregators or {}
|
|
40
45
|
|
|
41
46
|
def bars(self, instrument_id: str, interval: str = "1m", lookback: int | None = None) -> tuple[Bar, ...]:
|
|
42
47
|
if instrument_id != self._instrument_id:
|
|
@@ -57,11 +62,14 @@ class MarketView:
|
|
|
57
62
|
stop = self._visible
|
|
58
63
|
start = 0 if lookback is None else max(0, stop - lookback)
|
|
59
64
|
return tuple(self._minutes[start:stop])
|
|
65
|
+
# The aggregator path slices before building the tuple, so a lookback costs the
|
|
66
|
+
# window rather than every bucket accumulated so far.
|
|
67
|
+
aggregator = self._aggregators.get(interval)
|
|
68
|
+
if aggregator is not None:
|
|
69
|
+
return aggregator.tail(lookback)
|
|
60
70
|
found = self._aggregates.get(interval)
|
|
61
71
|
if found is None:
|
|
62
72
|
raise ContextError(f"Series '{interval}' is not available in this run")
|
|
63
|
-
# Aggregates are already immutable tuples ending at the cutoff, so slicing one
|
|
64
|
-
# copies only what was asked for.
|
|
65
73
|
return found if lookback is None else found[-lookback:]
|
|
66
74
|
|
|
67
75
|
|
|
@@ -169,3 +177,13 @@ class SeriesSet:
|
|
|
169
177
|
|
|
170
178
|
def snapshot(self) -> dict[str, tuple[Bar, ...]]:
|
|
171
179
|
return {interval: agg.snapshot() for interval, agg in self._aggregators.items()}
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def aggregators(self) -> Mapping[str, TimeframeAggregator]:
|
|
183
|
+
"""The live aggregators, for a reader that wants only a tail.
|
|
184
|
+
|
|
185
|
+
Handed over instead of a snapshot so the slice happens before the tuple is
|
|
186
|
+
built. Materializing every bucket on every bar is the cost this avoids; the
|
|
187
|
+
aggregators are only read through `tail`, which returns a new tuple.
|
|
188
|
+
"""
|
|
189
|
+
return self._aggregators
|
|
@@ -236,7 +236,10 @@ class Engine:
|
|
|
236
236
|
|
|
237
237
|
def _context(self, bar: Bar, visible: int, bars: list[Bar], series: SeriesSet) -> StrategyContext:
|
|
238
238
|
instrument = self._config.instrument
|
|
239
|
-
|
|
239
|
+
# Aggregators rather than snapshots: this runs once per bar, and materializing
|
|
240
|
+
# every derived bucket here cost 14.5 us/bar at 4,000 buckets against 1.9 us/bar
|
|
241
|
+
# for the tail a strategy actually reads.
|
|
242
|
+
market = MarketView(instrument.inst_id, bars, visible, aggregators=series.aggregators)
|
|
240
243
|
return StrategyContext(
|
|
241
244
|
kind="bar",
|
|
242
245
|
as_of_ms=bar.close_time_ms,
|
|
@@ -133,7 +133,7 @@ class LiveSession:
|
|
|
133
133
|
instrument_id=self._instrument_id,
|
|
134
134
|
interval="1m",
|
|
135
135
|
bar=bar,
|
|
136
|
-
market=MarketView(self._instrument_id, self._bars, len(self._bars), self._series.
|
|
136
|
+
market=MarketView(self._instrument_id, self._bars, len(self._bars), aggregators=self._series.aggregators),
|
|
137
137
|
portfolio=portfolio,
|
|
138
138
|
params=self._params,
|
|
139
139
|
indicators=IndicatorView(self._series.indicators, self._instrument_id, len(self._bars)),
|
|
@@ -191,3 +191,54 @@ def _check_handlers(tree: ast.Module) -> list[PolicyViolation]:
|
|
|
191
191
|
)
|
|
192
192
|
)
|
|
193
193
|
return found
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def discover_intervals(source: str) -> tuple[list[str], bool]:
|
|
197
|
+
"""Finds the higher timeframes a strategy reads, from the source alone.
|
|
198
|
+
|
|
199
|
+
Higher timeframes are aggregated incrementally: an aggregator has to see every
|
|
200
|
+
one-minute bar from the start, so one cannot be created partway through a run.
|
|
201
|
+
Declaring them was therefore a real requirement — but the declaration duplicated
|
|
202
|
+
something the source already states, and getting it wrong failed at bar one with
|
|
203
|
+
"Series '15m' is not available in this run".
|
|
204
|
+
|
|
205
|
+
Returns the intervals found as literals, and whether any call could not be read
|
|
206
|
+
statically. A `bars(id, chosen)` where `chosen` is computed cannot be resolved
|
|
207
|
+
here, so the caller keeps the explicit list as the way to cover that.
|
|
208
|
+
|
|
209
|
+
Deliberately syntactic. It matches `.bars(...)` by attribute name and takes only
|
|
210
|
+
string literals in the interval position, so it never runs strategy code and
|
|
211
|
+
cannot be tricked into reporting an interval that will not be requested. Over-
|
|
212
|
+
reporting is harmless (an unused aggregator costs one pass over the bars);
|
|
213
|
+
under-reporting is what the returned flag warns about.
|
|
214
|
+
"""
|
|
215
|
+
try:
|
|
216
|
+
tree = ast.parse(source)
|
|
217
|
+
except SyntaxError:
|
|
218
|
+
return [], False
|
|
219
|
+
|
|
220
|
+
found: set[str] = set()
|
|
221
|
+
dynamic = False
|
|
222
|
+
for node in ast.walk(tree):
|
|
223
|
+
if not isinstance(node, ast.Call):
|
|
224
|
+
continue
|
|
225
|
+
function = node.func
|
|
226
|
+
if not isinstance(function, ast.Attribute) or function.attr != "bars":
|
|
227
|
+
continue
|
|
228
|
+
argument = _interval_argument(node)
|
|
229
|
+
if argument is None:
|
|
230
|
+
continue
|
|
231
|
+
if isinstance(argument, ast.Constant) and isinstance(argument.value, str):
|
|
232
|
+
found.add(argument.value)
|
|
233
|
+
else:
|
|
234
|
+
dynamic = True
|
|
235
|
+
return sorted(item for item in found if item != "1m"), dynamic
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _interval_argument(node: ast.Call) -> ast.expr | None:
|
|
239
|
+
"""The interval argument of a `bars` call, positional or by keyword."""
|
|
240
|
+
for keyword in node.keywords:
|
|
241
|
+
if keyword.arg == "interval":
|
|
242
|
+
return keyword.value
|
|
243
|
+
# bars(instrument_id, interval, ...) — the instrument is first.
|
|
244
|
+
return node.args[1] if len(node.args) > 1 else None
|
|
@@ -21,7 +21,7 @@ from .actions import StrategyError
|
|
|
21
21
|
from .engine import Costs, Engine, Instrument, RunConfig, Sizing
|
|
22
22
|
from .indicators import IndicatorError
|
|
23
23
|
from .live import LiveSession, parse_portfolio
|
|
24
|
-
from .policy import validate_source
|
|
24
|
+
from .policy import discover_intervals, validate_source
|
|
25
25
|
from .report import build_report, calculate_metrics
|
|
26
26
|
from .timeframe import Bar, DataContractError, ONE_MINUTE_MS, interval_ms
|
|
27
27
|
|
|
@@ -170,7 +170,7 @@ def _backtest(request: dict[str, Any]) -> dict[str, Any]:
|
|
|
170
170
|
bars = _parse_bars(request.get("bars"))
|
|
171
171
|
config = _parse_config(request)
|
|
172
172
|
params = dict(request.get("params") or {})
|
|
173
|
-
intervals = _parse_intervals(request.get("intervals"))
|
|
173
|
+
intervals = _parse_intervals(request.get("intervals"), source)
|
|
174
174
|
handlers = _load_handlers(source)
|
|
175
175
|
|
|
176
176
|
total = len(bars)
|
|
@@ -182,6 +182,10 @@ def _backtest(request: dict[str, Any]) -> dict[str, Any]:
|
|
|
182
182
|
"protocol": PROTOCOL_VERSION,
|
|
183
183
|
"barCount": total,
|
|
184
184
|
"preloadBars": config.preload_bars,
|
|
185
|
+
# Reported because the engine resolves this, not the caller: intervals read from
|
|
186
|
+
# the source are added to whatever was requested, so the request is no longer
|
|
187
|
+
# what the run used. A report naming the request would state the wrong thing.
|
|
188
|
+
"intervals": intervals,
|
|
185
189
|
"report": report,
|
|
186
190
|
}
|
|
187
191
|
|
|
@@ -224,7 +228,7 @@ def _live(request: dict[str, Any]) -> int:
|
|
|
224
228
|
_emit({"ok": False, "error": {"code": "bad_request", "message": "instrument.instId is required"}})
|
|
225
229
|
return 2
|
|
226
230
|
instrument_id = str(instrument_raw["instId"])
|
|
227
|
-
intervals = _parse_intervals(request.get("intervals"))
|
|
231
|
+
intervals = _parse_intervals(request.get("intervals"), source)
|
|
228
232
|
handlers = _load_handlers(source)
|
|
229
233
|
session = LiveSession(instrument_id, handlers, dict(request.get("params") or {}), intervals)
|
|
230
234
|
|
|
@@ -309,7 +313,7 @@ def _optimize(request: dict[str, Any]) -> dict[str, Any]:
|
|
|
309
313
|
|
|
310
314
|
bars = _parse_bars(request.get("bars"))
|
|
311
315
|
base_config = _parse_config(request)
|
|
312
|
-
intervals = _parse_intervals(request.get("intervals"))
|
|
316
|
+
intervals = _parse_intervals(request.get("intervals"), source)
|
|
313
317
|
handlers = _load_handlers(source)
|
|
314
318
|
segments = _parse_segments(request.get("segments"), len(bars))
|
|
315
319
|
candidates = _parse_candidates(request.get("candidates"))
|
|
@@ -470,17 +474,40 @@ def _parse_bars(value: Any) -> list[Bar]:
|
|
|
470
474
|
return bars
|
|
471
475
|
|
|
472
476
|
|
|
473
|
-
def _parse_intervals(value: Any) -> list[str]:
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
+
def _parse_intervals(value: Any, source: str | None = None) -> list[str]:
|
|
478
|
+
"""Resolves which timeframes to aggregate for a run.
|
|
479
|
+
|
|
480
|
+
Anything the request names is honoured, and anything the source visibly reads is
|
|
481
|
+
added to it. Requiring the declaration meant a strategy calling
|
|
482
|
+
`ctx.market.bars(id, "15m")` failed on its first bar over a fact its own source
|
|
483
|
+
already stated. Reading it instead removes a step that could only be got wrong.
|
|
484
|
+
|
|
485
|
+
The request still matters. A timeframe reached through a computed name cannot be
|
|
486
|
+
found by reading the source, so naming it explicitly remains the way to cover
|
|
487
|
+
that; and an interval named but never used costs only one pass over the bars.
|
|
488
|
+
"""
|
|
489
|
+
if value is not None and not isinstance(value, list):
|
|
477
490
|
raise DataContractError("'intervals' must be an array of interval names")
|
|
478
491
|
intervals = ["1m"]
|
|
479
|
-
for item in value:
|
|
492
|
+
for item in value or []:
|
|
480
493
|
name = str(item)
|
|
481
494
|
interval_ms(name)
|
|
482
495
|
if name not in intervals:
|
|
483
496
|
intervals.append(name)
|
|
497
|
+
if source is not None:
|
|
498
|
+
discovered, _ = discover_intervals(source)
|
|
499
|
+
for name in discovered:
|
|
500
|
+
# Validated like a declared one, but named as read from the source: the
|
|
501
|
+
# strategy would reach that line and fail anyway, so failing now with the
|
|
502
|
+
# reason is strictly better than failing on bar one without it.
|
|
503
|
+
try:
|
|
504
|
+
interval_ms(name)
|
|
505
|
+
except DataContractError as error:
|
|
506
|
+
raise DataContractError(
|
|
507
|
+
f"The strategy reads interval '{name}', which cannot be aggregated. {error}"
|
|
508
|
+
) from error
|
|
509
|
+
if name not in intervals:
|
|
510
|
+
intervals.append(name)
|
|
484
511
|
return intervals
|
|
485
512
|
|
|
486
513
|
|
|
@@ -139,6 +139,23 @@ class TimeframeAggregator:
|
|
|
139
139
|
return tuple(self._completed)
|
|
140
140
|
return (*self._completed, self._current)
|
|
141
141
|
|
|
142
|
+
def tail(self, lookback: int | None) -> tuple[Bar, ...]:
|
|
143
|
+
"""The last `lookback` buckets, or all of them when it is None.
|
|
144
|
+
|
|
145
|
+
Sliced before the tuple is built. `snapshot()` copies every accumulated bucket,
|
|
146
|
+
and it is called once per one-minute bar, so a 180-day run over 15m and 1H
|
|
147
|
+
rebuilt ~21,600 elements 260,000 times. Measured at 4,000 buckets: 14.5 us/bar
|
|
148
|
+
for the full snapshot against 1.9 us/bar for a 96-bucket tail.
|
|
149
|
+
"""
|
|
150
|
+
if lookback is None:
|
|
151
|
+
return self.snapshot()
|
|
152
|
+
if self._current is None:
|
|
153
|
+
return tuple(self._completed[-lookback:])
|
|
154
|
+
# The forming bucket occupies one slot of the requested window.
|
|
155
|
+
if lookback <= 1:
|
|
156
|
+
return (self._current,)
|
|
157
|
+
return (*self._completed[-(lookback - 1):], self._current)
|
|
158
|
+
|
|
142
159
|
def latest(self) -> Bar | None:
|
|
143
160
|
return self._current
|
|
144
161
|
|