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 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 0ad1fd0cb6d49a6ceca5b70175f0ebeeaa207b6d.
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.4.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.4.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(