outcometick 1.4.1 → 1.5.0
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 +32 -1
- package/api/lib/backtest-contract.mjs +1 -1
- package/package.json +6 -2
- package/runner/analyze/python_analyze.py +20 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
scripts/publish-sdk-repos.mjs and overwritten wholesale on each publish.
|
|
6
6
|
An edit made here survives until the next publish and then disappears.
|
|
7
7
|
|
|
8
|
-
Generated from monorepo revision
|
|
8
|
+
Generated from monorepo revision c210f1ac8cbf693e62cc5b3c5580b0f8663e495a.
|
|
9
9
|
-->
|
|
10
10
|
|
|
11
11
|
# outcometick
|
|
@@ -79,6 +79,37 @@ npm install && npm test
|
|
|
79
79
|
Requires `python3` on PATH: one of the two static analysers is written in
|
|
80
80
|
Python, and the CLI drives it the same way the API does.
|
|
81
81
|
|
|
82
|
+
## Downloading data
|
|
83
|
+
|
|
84
|
+
The other half of the package: a client for the data subscription, on a
|
|
85
|
+
separate import because it has nothing to do with writing a strategy.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { DataClient, NO_VALUE } from "outcometick/data";
|
|
89
|
+
|
|
90
|
+
const ot = new DataClient(); // key from OT_KEY
|
|
91
|
+
|
|
92
|
+
const meta = await ot.meta(); // what can this key see?
|
|
93
|
+
|
|
94
|
+
const { files } = await ot.files({
|
|
95
|
+
from: "2026-08-01", to: "2026-08-12", // or date: "2026-08-12"
|
|
96
|
+
asset: ["BTCUSD", "ETHUSD"], // an array means "any of these"
|
|
97
|
+
dataset: "prices",
|
|
98
|
+
interval: ["5m", NO_VALUE], // "5m" alone EXCLUDES the
|
|
99
|
+
}); // period-less settlement streams
|
|
100
|
+
|
|
101
|
+
await ot.download(files[0], { saveTo: files[0].name }); // checksum verified
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`meta()` reports the dimensions this key can actually reach. Note that
|
|
105
|
+
`intervals` holds real durations only — the `none` sentinel is reported
|
|
106
|
+
separately under `filterTokens`, so a caller that builds an enum from it or
|
|
107
|
+
parses the values as durations never meets a token.
|
|
108
|
+
|
|
109
|
+
Downloads are checksum-verified: `/v1/dl` redirects to storage with the sha256
|
|
110
|
+
in a header, and the client follows that redirect itself so the checksum is not
|
|
111
|
+
thrown away.
|
|
112
|
+
|
|
82
113
|
---
|
|
83
114
|
|
|
84
115
|
Writing your strategy in Python instead? The SDK for it is
|
|
@@ -15,7 +15,7 @@ import { FIRST_COMPLETE_DAY } from './coverage-window.mjs';
|
|
|
15
15
|
export const SCHEMA_VERSION = 1;
|
|
16
16
|
|
|
17
17
|
/** SDK version reported by the docs page and stamped into every report. */
|
|
18
|
-
export const SDK_VERSION = '1.
|
|
18
|
+
export const SDK_VERSION = '1.5.0';
|
|
19
19
|
|
|
20
20
|
// ---------------------------------------------------------------------------
|
|
21
21
|
// Languages
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "outcometick",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Strategy SDK and CLI for outcometick prediction-market backtests",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
".": {
|
|
21
21
|
"types": "./index.d.ts",
|
|
22
22
|
"default": "./index.mjs"
|
|
23
|
+
},
|
|
24
|
+
"./data": {
|
|
25
|
+
"types": "./client/data.d.ts",
|
|
26
|
+
"default": "./client/data.mjs"
|
|
23
27
|
}
|
|
24
28
|
},
|
|
25
29
|
"engines": {
|
|
@@ -36,7 +40,7 @@
|
|
|
36
40
|
"!**/*.test-d.ts"
|
|
37
41
|
],
|
|
38
42
|
"scripts": {
|
|
39
|
-
"test": "node --test runner/analyze/*.test.mjs runner/engine/*.test.mjs runner/harness/node/*.test.mjs cli/*.test.mjs"
|
|
43
|
+
"test": "node --test runner/analyze/*.test.mjs runner/engine/*.test.mjs runner/harness/node/*.test.mjs cli/*.test.mjs client/*.test.mjs"
|
|
40
44
|
},
|
|
41
45
|
"dependencies": {
|
|
42
46
|
"acorn": "^8.18.0"
|
|
@@ -145,6 +145,26 @@ def check_import(module, name, line, deps, relative_ok):
|
|
|
145
145
|
else "E_FORBIDDEN"
|
|
146
146
|
)
|
|
147
147
|
raise Reject(code, f"{name}:{line}: import {root} — {FORBIDDEN_IMPORTS[root]}", name, line)
|
|
148
|
+
# `outcometick` is allowed as the SDK module and nothing else. In the
|
|
149
|
+
# sandbox it is a single flat module -- Strategy and Order -- so
|
|
150
|
+
# `outcometick.data` resolves to nothing there, even though pip installs it
|
|
151
|
+
# as a real submodule. Allowing it because the ROOT matches would mean
|
|
152
|
+
# `ot check` passing a strategy that dies on import after being queued,
|
|
153
|
+
# which is the exact failure the "if it passes locally it will not be
|
|
154
|
+
# rejected on submit" promise exists to prevent.
|
|
155
|
+
#
|
|
156
|
+
# The JavaScript analyser has always compared the whole specifier, so
|
|
157
|
+
# `outcometick/data` was already refused there. This is the Python half of
|
|
158
|
+
# the same rule.
|
|
159
|
+
if root == "outcometick" and module != "outcometick":
|
|
160
|
+
raise Reject(
|
|
161
|
+
"E_IMPORT",
|
|
162
|
+
f"{name}:{line}: import of {module!r} — only 'outcometick' itself is "
|
|
163
|
+
"available to a strategy; the sandbox has no network and no submodules",
|
|
164
|
+
name,
|
|
165
|
+
line,
|
|
166
|
+
specifier=module,
|
|
167
|
+
)
|
|
148
168
|
if root in ALWAYS_ALLOWED or root in deps:
|
|
149
169
|
return
|
|
150
170
|
raise Reject(
|