nexusquant-cli 0.2.0__tar.gz → 0.3.0__tar.gz
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.
- nexusquant_cli-0.3.0/CLAUDE.md +59 -0
- nexusquant_cli-0.3.0/PKG-INFO +375 -0
- nexusquant_cli-0.3.0/README.md +361 -0
- nexusquant_cli-0.3.0/docs/investor-operations.md +60 -0
- nexusquant_cli-0.3.0/nexusquant_cli/__init__.py +1 -0
- nexusquant_cli-0.3.0/nexusquant_cli/api_client.py +362 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/auth_pkce.py +2 -2
- nexusquant_cli-0.3.0/nexusquant_cli/commands/__init__.py +16 -0
- nexusquant_cli-0.3.0/nexusquant_cli/commands/_util.py +61 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/config.py +16 -0
- nexusquant_cli-0.3.0/nexusquant_cli/embedded.py +80 -0
- nexusquant_cli-0.3.0/nexusquant_cli/identity.py +59 -0
- nexusquant_cli-0.3.0/nexusquant_cli/nexus.py +48 -0
- nexusquant_cli-0.3.0/nexusquant_cli/roles/__init__.py +0 -0
- nexusquant_cli-0.3.0/nexusquant_cli/roles/_agent.py +193 -0
- nexusquant_cli-0.3.0/nexusquant_cli/roles/admin.py +272 -0
- nexusquant_cli-0.3.0/nexusquant_cli/roles/auth.py +91 -0
- nexusquant_cli-0.3.0/nexusquant_cli/roles/investor.py +637 -0
- nexusquant_cli-0.3.0/nexusquant_cli/roles/provider.py +141 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/pyproject.toml +6 -2
- nexusquant_cli-0.3.0/tests/__init__.py +0 -0
- nexusquant_cli-0.3.0/tests/test_nexus_cli.py +494 -0
- nexusquant_cli-0.3.0/uv.lock +345 -0
- nexusquant_cli-0.2.0/CLAUDE.md +0 -66
- nexusquant_cli-0.2.0/PKG-INFO +0 -139
- nexusquant_cli-0.2.0/README.md +0 -127
- nexusquant_cli-0.2.0/dist_archive/nexusquant_cli-0.1.1-py3-none-any.whl +0 -0
- nexusquant_cli-0.2.0/dist_archive/nexusquant_cli-0.1.1.tar.gz +0 -0
- nexusquant_cli-0.2.0/dist_archive/nexusquant_cli-0.1.2-py3-none-any.whl +0 -0
- nexusquant_cli-0.2.0/dist_archive/nexusquant_cli-0.1.2.tar.gz +0 -0
- nexusquant_cli-0.2.0/nexusquant_cli/__init__.py +0 -1
- nexusquant_cli-0.2.0/nexusquant_cli/api_client.py +0 -83
- nexusquant_cli-0.2.0/nexusquant_cli/commands/__init__.py +0 -13
- nexusquant_cli-0.2.0/nexusquant_cli/commands/_util.py +0 -36
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/.gitignore +0 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/__main__.py +0 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/commands/auth/__init__.py +0 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/commands/auth/cmd.py +0 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/commands/policy/__init__.py +0 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/commands/policy/cmd.py +0 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/commands/strategy/__init__.py +0 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/commands/strategy/cmd.py +0 -0
- {nexusquant_cli-0.2.0 → nexusquant_cli-0.3.0}/nexusquant_cli/main.py +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# nexusquant-cli
|
|
2
|
+
|
|
3
|
+
Python CLI for NexusQuant users, strategy providers and admins. Cognito PKCE browser login, token storage/refresh, and wrappers over the nexus-service REST API.
|
|
4
|
+
|
|
5
|
+
Two entry points, one login (credentials shared with nexusquant-sdk under `platformdirs/nexusquant-sdk/credentials.json`):
|
|
6
|
+
|
|
7
|
+
- `nexus-cli` (`nexusquant_cli/nexus.py`) — `nexus-cli <role> <verb> <resource>`; roles `investor` / `provider` / `admin`, plus `auth`.
|
|
8
|
+
- `nexusquant` (`nexusquant_cli/main.py`) — legacy flat provider layout. Keep it working: scheduled tasks and the nexus-admin webhook-adapter skill call it, and `webhook_admin.py` imports `nexusquant_cli.api_client`, `config` and `auth_pkce.ensure_fresh_id_token` directly.
|
|
9
|
+
|
|
10
|
+
## Code structure
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
nexusquant_cli/
|
|
14
|
+
nexus.py # nexus-cli entry (role groups)
|
|
15
|
+
main.py # legacy nexusquant entry
|
|
16
|
+
roles/ # auth / investor / provider / admin — verb-first sub-apps
|
|
17
|
+
# provider.py mounts the functions from commands/ rather than copying them
|
|
18
|
+
commands/ # legacy command bodies (auth, strategy, policy) + _util (fail / JSON helpers)
|
|
19
|
+
api_client.py # HTTP wrapper; ApiError; retries once on stale-Wall-Pro 403
|
|
20
|
+
identity.py # decode local ID token for whoami / 403 hints (display only, never gates)
|
|
21
|
+
auth_pkce.py # Cognito PKCE flow
|
|
22
|
+
config.py # endpoints, credential path
|
|
23
|
+
docs/investor-operations.md # investor API surface survey + phase-2 roadmap
|
|
24
|
+
tests/ # pytest, httpx.MockTransport — no network
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Tests: `pip install -e '.[dev]' && python -m pytest -q tests`.
|
|
28
|
+
|
|
29
|
+
Investor commands deliberately exclude anything that arms auto-trading, changes sizing, or touches broker secrets — see docs/investor-operations.md before adding those.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Development (editable)
|
|
35
|
+
pip install -e .
|
|
36
|
+
|
|
37
|
+
# From PyPI
|
|
38
|
+
pip install nexusquant-cli
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
See README.md.
|
|
44
|
+
|
|
45
|
+
## Deploy / publish
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Build distribution
|
|
49
|
+
python -m build
|
|
50
|
+
|
|
51
|
+
# Publish to PyPI
|
|
52
|
+
twine upload dist/*
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Configuration
|
|
56
|
+
|
|
57
|
+
API base URL is set in `nexusquant_cli/config.py`. Change `API_BASE_URL` to point at a different environment (staging vs production).
|
|
58
|
+
|
|
59
|
+
Provider commands need `custom:userType=strategyProvider` or admin; admin commands need admin (or the `admin` Cognito group). User commands work for any login; some need Wall Pro.
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: nexusquant-cli
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: NexusQuant CLI for users, strategy providers and admins
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: httpx>=0.27
|
|
7
|
+
Requires-Dist: nexusquant-sdk>=0.2
|
|
8
|
+
Requires-Dist: platformdirs>=4.2
|
|
9
|
+
Requires-Dist: rich>=13.7
|
|
10
|
+
Requires-Dist: typer>=0.12
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# nexusquant-cli
|
|
16
|
+
|
|
17
|
+
Command line tool for NexusQuant investors, strategy providers and admins.
|
|
18
|
+
|
|
19
|
+
It supports browser login through Cognito, stores tokens locally, refreshes tokens, and calls the Nexus APIs. Two entry points share one login:
|
|
20
|
+
|
|
21
|
+
- **`nexus-cli`** — role-first grammar, `nexus-cli <role> <verb> <resource> [args]`. Use this.
|
|
22
|
+
- `nexusquant` — the original flat provider layout (`nexusquant strategy|policy …`), kept unchanged for existing scripts. Everything below the `nexus-cli` section documents it.
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
python3 -m pip install -e .
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install nexusquant-cli
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## nexus-cli
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
nexus-cli auth login # browser login; one login covers every role
|
|
38
|
+
nexus-cli auth whoami # account, userType, Wall Pro tier, usable roles
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The role is not picked at login — it is the account's `custom:userType` (or the `admin` Cognito group), and the server checks it on every call. `whoami` reads it from the local token; on a 403 the CLI prints which account type is logged in.
|
|
42
|
+
|
|
43
|
+
Every read takes `--json` for scripting; the default output is a table.
|
|
44
|
+
|
|
45
|
+
### investor — any logged-in account
|
|
46
|
+
|
|
47
|
+
| Command | What it does |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `investor list strategies [--subscribed]` | Marketplace, with backtest summary and a flag for strategies whose sizing reads your holdings |
|
|
50
|
+
| `investor read strategy <id>` | Detail + 30 most recent signals |
|
|
51
|
+
| `investor read backtest <id>` | Backtest stats, rolling returns, per-ticker attribution, return since you added it |
|
|
52
|
+
| `investor subscribe strategy <id>...` | Add to My Strategies (Wall Pro). **Does not start auto-trading** |
|
|
53
|
+
| `investor unsubscribe strategy <id> [-y]` | Remove from My Strategies; asks first, and warns if it is listening (this stops auto-trading) |
|
|
54
|
+
| `investor list subscriptions` | My Strategies: listening on/off, config saved, broker |
|
|
55
|
+
| `investor read config <id>` | Your personal config, effective config, and the schema of what you can set |
|
|
56
|
+
| `investor list signals [--strategy-id --status --direction --limit --offset]` | Signals that reached you, with your own broker result for each |
|
|
57
|
+
| `investor read stats` | Signal counts and broker success rate |
|
|
58
|
+
| `investor read profile` / `investor read settings` | Account; daily-report setting |
|
|
59
|
+
| `investor update settings --daily-report/--no-daily-report` | Toggle the daily report email |
|
|
60
|
+
| `investor read container` | Trading environment state, broker login, selected account |
|
|
61
|
+
| `investor list brokers` | Supported brokers and their login fields |
|
|
62
|
+
| `investor list activity` | Your own activity log |
|
|
63
|
+
|
|
64
|
+
#### Nexus AI agent — permissions and logs
|
|
65
|
+
|
|
66
|
+
Nexus AI is the agent you chat with in the web app. Commands for the agent are under `investor`, and you can only **narrow** what it may do. The ceiling comes from your profile and is enforced on the agent host.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
nexus-cli investor read agent-access # enabled?, profile, tools, extra denied tools
|
|
70
|
+
nexus-cli investor update agent-access --profile readonly # investor | readonly (admins: operator) | default
|
|
71
|
+
nexus-cli investor update agent-access --deny-tool Write --deny-tool Edit
|
|
72
|
+
nexus-cli investor update agent-access --clear-deny
|
|
73
|
+
nexus-cli investor list agent-sessions # past conversations: title, turns, tool calls, denials, cost
|
|
74
|
+
nexus-cli investor read agent-session ws-… # the full conversation, as it happened
|
|
75
|
+
nexus-cli investor delete agent-session ws-… # remove it from your history (soft delete)
|
|
76
|
+
nexus-cli investor list agent-logs --denied # every refused tool call
|
|
77
|
+
nexus-cli investor list agent-logs --session ws-… --event tool_executed
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
| Profile | Tools | Files |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `investor` | Read, Glob, Grep, Write, Edit, MultiEdit, TodoWrite, WebSearch. No shell, no sub-agents, no WebFetch | Only your own workspace |
|
|
83
|
+
| `readonly` | `investor` without the write tools | Only your own workspace |
|
|
84
|
+
| `operator` (admins only) | Everything | The whole agent workspace |
|
|
85
|
+
|
|
86
|
+
- Conversations are kept permanently so you can read your history. Deleting one hides it from you; the platform keeps a copy, and admins can still see it.
|
|
87
|
+
- Audit entries (the per-tool-call log) are kept for 90 days.
|
|
88
|
+
- Changes apply to sessions opened afterwards.
|
|
89
|
+
- Every tool call is logged: which tool, a summary of its input, and whether it was auto-allowed, approved by you, or refused. Refusals record who refused it: the profile, you, or a timeout.
|
|
90
|
+
- Each turn also logs its cost.
|
|
91
|
+
|
|
92
|
+
Not in the CLI yet, on purpose: switching listening on (arms auto-trading), editing sizing config, broker connect, container start/stop/reset, and webhook strategies. They place real orders or carry broker secrets and need their own confirmation / secret-handling design — see `docs/investor-operations.md`.
|
|
93
|
+
|
|
94
|
+
### provider — `custom:userType=strategyProvider` or admin
|
|
95
|
+
|
|
96
|
+
| Command | Same as legacy |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `provider create strategy -i ID -n NAME [--schema-file …]` | `nexusquant strategy create` |
|
|
99
|
+
| `provider list strategies` | `nexusquant strategy list` |
|
|
100
|
+
| `provider list signals <id> [--limit --offset --status --direction]` | `nexusquant strategy signal <id> --history` |
|
|
101
|
+
| `provider send signal <id> --ticker … --direction … --price … --quantity …` / `--signals-file` | `nexusquant strategy signal <id> --ticker …` |
|
|
102
|
+
| `provider list subscribers <id>` | `nexusquant strategy sub config <id>` |
|
|
103
|
+
| `provider list features [--scope --json]` | `nexusquant policy features` |
|
|
104
|
+
| `provider publish policy --strategy-id … --ticker … --file …` | `nexusquant policy publish` |
|
|
105
|
+
| `provider list policies <id>` | `nexusquant policy list` |
|
|
106
|
+
| `provider update policy --policy-id … --mode off` | `nexusquant policy set-mode` |
|
|
107
|
+
| `provider send policy-signal …` | `nexusquant policy send-signal` |
|
|
108
|
+
|
|
109
|
+
Options are identical to the legacy commands documented below. One difference: `provider send signal` with no send fields is an error, where the legacy `strategy signal` silently listed history.
|
|
110
|
+
|
|
111
|
+
### admin — `custom:userType=admin`
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
nexus-cli admin list reviews [--status all] [--verbose]
|
|
115
|
+
nexus-cli admin review strategy <id> --action approve|reject|suspend [--note …]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
nexus-cli admin list agent-access # who besides admins may use Nexus AI
|
|
120
|
+
nexus-cli admin grant agent-access --email someone@x.com
|
|
121
|
+
nexus-cli admin revoke agent-access --email someone@x.com
|
|
122
|
+
nexus-cli admin list agent-sessions [--email … | --user-id …] [--include-deleted]
|
|
123
|
+
nexus-cli admin read agent-session ws-… # any user's conversation; each read goes into your admin activity log
|
|
124
|
+
nexus-cli admin list agent-logs --email someone@x.com --denied
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
How grant and revoke take effect:
|
|
128
|
+
- Granting adds the user to the `NEXUS_AI_USERS` flag. Non-admins can only connect once the backend's `NEXUS_AI_BRIDGE_POLICY` is also on.
|
|
129
|
+
- Revoking refuses new connections within about 30 seconds. A session that is already open closes at its next token renewal; the web app renews every 20 minutes.
|
|
130
|
+
|
|
131
|
+
Agent ops (weekly analysis uploads, S3 reads, Discord KB, notify) stay in `nexus-agent` (nexus-agent-cli) for now.
|
|
132
|
+
|
|
133
|
+
## Legacy `nexusquant` commands
|
|
134
|
+
|
|
135
|
+
### Login
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
nexusquant auth
|
|
139
|
+
nexusquant auth --status
|
|
140
|
+
nexusquant auth --refresh
|
|
141
|
+
nexusquant auth --logout
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Tokens are stored in the current OS user's config directory, for example `~/Library/Application Support/nexusquant-cli/credentials.json` on macOS. The file is written with `0600` permissions when supported.
|
|
145
|
+
|
|
146
|
+
## Strategy Commands
|
|
147
|
+
|
|
148
|
+
Create or update a strategy:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
nexusquant strategy create \
|
|
152
|
+
--strategy-id my_alpha_001 \
|
|
153
|
+
--name "My Alpha" \
|
|
154
|
+
--schema-file schema.json \
|
|
155
|
+
--output-unit SHARE_COUNT
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
List strategies registered by the current provider. Admin users see all strategies:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
nexusquant strategy list
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
List signal history for one strategy:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
nexusquant strategy signal my_alpha_001 --history --limit 20
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Send a single signal:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
nexusquant strategy signal my_alpha_001 \
|
|
174
|
+
--strategy-name "My Alpha" \
|
|
175
|
+
--ticker AAPL \
|
|
176
|
+
--direction buy \
|
|
177
|
+
--price 150.25 \
|
|
178
|
+
--quantity 100 \
|
|
179
|
+
--order-type MARKET
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`--order-type` is a signal-level setting: `MARKET` or `LIMIT` (limit uses `--price`). Legacy `NORMAL` is accepted by the CLI as an alias for `LIMIT`. If omitted, the API defaults to `MARKET`.
|
|
183
|
+
|
|
184
|
+
Send a multi-route `signals` map:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
nexusquant strategy signal my_alpha_001 \
|
|
188
|
+
--strategy-name "My Alpha" \
|
|
189
|
+
--signals-file signals.json
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Get non-PII subscriber config for a strategy:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
nexusquant strategy sub config my_alpha_001
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Policy Commands
|
|
199
|
+
|
|
200
|
+
A SizingPolicy replaces the fixed `--quantity` on a signal with a **formula** that
|
|
201
|
+
decides the order quantity — and optionally a limit price — at order time. You
|
|
202
|
+
publish the formula once; each signal then carries only the parameter values it
|
|
203
|
+
needs. Values that depend on the individual subscriber's account are never sent by
|
|
204
|
+
you: they are bound inside that user's own container when the order is placed.
|
|
205
|
+
|
|
206
|
+
Requires `custom:userType=strategyProvider` or `admin`, the same as the strategy
|
|
207
|
+
commands.
|
|
208
|
+
|
|
209
|
+
### See which names a formula may use
|
|
210
|
+
|
|
211
|
+
The server registry is the authority — a name outside it cannot be published. Run
|
|
212
|
+
this before writing a formula:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
nexusquant policy features
|
|
216
|
+
nexusquant policy features --scope shared # names you send with each signal
|
|
217
|
+
nexusquant policy features --scope account # names bound in the user's container
|
|
218
|
+
nexusquant policy features --json # raw output for scripting
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Account-scoped names carry a "suppliable" flag: a name that exists but that the
|
|
222
|
+
container cannot currently supply will pass your editor and fail at publish.
|
|
223
|
+
|
|
224
|
+
### Publish a formula
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
nexusquant policy publish --strategy-id my_alpha --ticker TQQQ --file tqqq.json
|
|
228
|
+
nexusquant policy publish --strategy-id my_alpha --ticker TQQQ --file tqqq.json --profile normal
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
`--file` holds the two things a policy is made of — the formulas keyed by output
|
|
232
|
+
slot, and the names you promise to supply with every signal:
|
|
233
|
+
|
|
234
|
+
```json
|
|
235
|
+
{
|
|
236
|
+
"expr": {
|
|
237
|
+
"f_depth": "exp(-k_depth * depth / 10)",
|
|
238
|
+
"buy.quantity": "target_shares * f_depth * clamp(1 - pos_ratio, 0, 1)",
|
|
239
|
+
"buy.price": "ref_price * (1 - slip)",
|
|
240
|
+
"sell.quantity": "held_shares * exit_frac"
|
|
241
|
+
},
|
|
242
|
+
"params": ["target_shares", "k_depth", "depth", "ref_price", "slip", "exit_frac"]
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Output slots — the container picks the one matching the signal's direction:
|
|
247
|
+
|
|
248
|
+
| Slot | What the formula yields |
|
|
249
|
+
|---|---|
|
|
250
|
+
| `buy.quantity` / `sell.quantity` | **Share count** (floored) |
|
|
251
|
+
| `buy.price` / `sell.price` | **Limit price** — supplied ⇒ limit order, omitted ⇒ market order |
|
|
252
|
+
|
|
253
|
+
Intermediate names (`f_depth`) are fine, but an `expr` must define at least one
|
|
254
|
+
output slot, and an intermediate name may not contain a dot. `--ticker` is separate
|
|
255
|
+
from the file because it is not part of the artifact: the same formula pointed at
|
|
256
|
+
another symbol is the same formula.
|
|
257
|
+
|
|
258
|
+
⚠️ **`publish` IS the go-live action.** There is no shadow or canary step, and the
|
|
259
|
+
previous version on the same slot is deactivated. `--profile` defaults to `normal`.
|
|
260
|
+
|
|
261
|
+
Before sending anything, the CLI fetches the registry and checks locally that every
|
|
262
|
+
free name in your formula has someone to supply it — forgetting to list a name in
|
|
263
|
+
`params` is the most common mistake. `--skip-name-check` disables that fetch, and
|
|
264
|
+
then local success does not imply the server will accept.
|
|
265
|
+
|
|
266
|
+
### List and stop
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
nexusquant policy list my_alpha
|
|
270
|
+
nexusquant policy list my_alpha --ticker TQQQ --mode active # --mode active / off
|
|
271
|
+
|
|
272
|
+
# Emergency stop for a live version — not a promotion step, since publish already went live
|
|
273
|
+
nexusquant policy set-mode --policy-id 'TQQQ/normal/…/abc123' --mode off
|
|
274
|
+
nexusquant policy set-mode --policy-id 'TQQQ/normal/…/abc123' --mode active
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Send a signal against a policy
|
|
278
|
+
|
|
279
|
+
Every declared parameter must be present, or the signal is rejected:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
nexusquant policy send-signal \
|
|
283
|
+
--strategy-id my_alpha --ticker TQQQ --price 51.2 --direction buy \
|
|
284
|
+
-p target_shares=10 -p k_depth=0.5 -p depth=3 \
|
|
285
|
+
-p ref_price=51.2 -p slip=0.002 -p exit_frac=0.25
|
|
286
|
+
|
|
287
|
+
# Or pass all parameter values as a JSON object
|
|
288
|
+
nexusquant policy send-signal --strategy-id my_alpha --ticker TQQQ \
|
|
289
|
+
--price 51.2 --direction buy --params-file params.json
|
|
290
|
+
|
|
291
|
+
# Validate and print the payload without sending it
|
|
292
|
+
nexusquant policy send-signal ... --dry-run
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
| Flag | Meaning |
|
|
296
|
+
|---|---|
|
|
297
|
+
| `--param` / `-p` | One parameter value, `name=value`; repeat per declared name |
|
|
298
|
+
| `--params-file` | A JSON object with all parameter values instead |
|
|
299
|
+
| `--policy-id` | Defaults to the active policy on this `(strategy, ticker)` |
|
|
300
|
+
| `--quantity` | Used when the formula has no slot for this direction |
|
|
301
|
+
| `--order-type` | `MARKET` / `LIMIT` |
|
|
302
|
+
| `--strategy-name` | Defaults to the strategy id |
|
|
303
|
+
| `--no-fetch` | Skip fetching the policy — see below |
|
|
304
|
+
| `--dry-run` | Validate and print the payload, send nothing |
|
|
305
|
+
|
|
306
|
+
By default the CLI fetches the active policy first and uses it to validate and
|
|
307
|
+
coerce your values. Three checks, each mirroring the server:
|
|
308
|
+
|
|
309
|
+
| Situation | Result | Why not something else |
|
|
310
|
+
|---|---|---|
|
|
311
|
+
| A declared parameter is missing | Error | No defaults — a default turns "unknown" into "known" |
|
|
312
|
+
| A name you did not declare | Error | The formula cannot reference it; extra names mean the two sides disagree |
|
|
313
|
+
| An account-state name (`pos_ratio`, `held_shares`, …) | Error | Its value never leaves the execution plane |
|
|
314
|
+
|
|
315
|
+
`--no-fetch` skips the fetch, and then **only the account-state rule is checked** —
|
|
316
|
+
the rest is unknowable locally, so it is not pretended.
|
|
317
|
+
|
|
318
|
+
⚠️ **The server is always the authority.** Passing local validation does not mean
|
|
319
|
+
the server will accept — policy state and review status live there. This layer only
|
|
320
|
+
moves the obvious mistakes onto your machine, where you can see which field is
|
|
321
|
+
wrong instead of guessing from a rejection.
|
|
322
|
+
|
|
323
|
+
⚠️ **There is no publish-time bound on order size.** Parameters are names only,
|
|
324
|
+
with no declared domain, so nothing proves at publish time that a formula stays
|
|
325
|
+
under a limit. How large an order it can place is clamped at order time by the
|
|
326
|
+
subscriber's own `max_order_cash_usd`. Keep your formulas in a sane range yourself.
|
|
327
|
+
|
|
328
|
+
## JSON Inputs
|
|
329
|
+
|
|
330
|
+
`--schema-file` must contain the `strategy_schema` object accepted by `nexus-service`, for example:
|
|
331
|
+
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"type": "object",
|
|
335
|
+
"properties": {
|
|
336
|
+
"window": {
|
|
337
|
+
"type": "integer",
|
|
338
|
+
"default": 14,
|
|
339
|
+
"title": "Window",
|
|
340
|
+
"source": "user"
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
"required": []
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
`--signals-file` must contain a JSON object whose keys are `default` or user ids:
|
|
348
|
+
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"default": {
|
|
352
|
+
"ticker": "AAPL",
|
|
353
|
+
"time": "2026-04-26T19:30:00Z",
|
|
354
|
+
"price": 150.25,
|
|
355
|
+
"direction": "buy",
|
|
356
|
+
"order_type": "LIMIT",
|
|
357
|
+
"quantity": 100,
|
|
358
|
+
"metadata": {}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Environment Overrides
|
|
364
|
+
|
|
365
|
+
Normal use does not require configuration. For staging or local development:
|
|
366
|
+
|
|
367
|
+
| Variable | Meaning |
|
|
368
|
+
| ------------------------------ | ------------------------------------------------------------------------------------- |
|
|
369
|
+
| `NEXUSQUANT_API_ENDPOINT` | API endpoint host, default `https://api.nexusquant.co`; CLI calls `/api/...` under it |
|
|
370
|
+
| `NEXUSQUANT_API_BASE_URL` | Optional full API base override, e.g. `https://api.nexusquant.co/api` |
|
|
371
|
+
| `NEXUSQUANT_COGNITO_DOMAIN` | Cognito Hosted UI host, default `auth.lookatwallstreet.com` |
|
|
372
|
+
| `NEXUSQUANT_COGNITO_CLIENT_ID` | Cognito app client id |
|
|
373
|
+
| `NEXUSQUANT_REDIRECT_URI` | OAuth callback, default `http://127.0.0.1:8251/callback` |
|
|
374
|
+
|
|
375
|
+
There is also a hidden typo-compatible alias: `nexusquant startegy ...` maps to `nexusquant strategy ...`.
|