desic-okx-agent 0.2.1 → 0.3.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.
Files changed (236) hide show
  1. package/README.en.md +90 -10
  2. package/README.md +76 -10
  3. package/dist/account/private-websocket.js +4 -4
  4. package/dist/account/private-websocket.js.map +1 -1
  5. package/dist/account/service.d.ts +12 -1
  6. package/dist/account/service.js +18 -0
  7. package/dist/account/service.js.map +1 -1
  8. package/dist/bars/rate-limiter.d.ts +18 -0
  9. package/dist/bars/rate-limiter.js +84 -0
  10. package/dist/bars/rate-limiter.js.map +1 -0
  11. package/dist/bars/schema.d.ts +36 -0
  12. package/dist/bars/schema.js +134 -0
  13. package/dist/bars/schema.js.map +1 -0
  14. package/dist/bars/service.d.ts +60 -0
  15. package/dist/bars/service.js +120 -0
  16. package/dist/bars/service.js.map +1 -0
  17. package/dist/bars/store.d.ts +105 -0
  18. package/dist/bars/store.js +415 -0
  19. package/dist/bars/store.js.map +1 -0
  20. package/dist/bars/timeframe.d.ts +40 -0
  21. package/dist/bars/timeframe.js +146 -0
  22. package/dist/bars/timeframe.js.map +1 -0
  23. package/dist/bars/types.d.ts +68 -0
  24. package/dist/bars/types.js +13 -0
  25. package/dist/bars/types.js.map +1 -0
  26. package/dist/cli/data-render.d.ts +37 -0
  27. package/dist/cli/data-render.js +143 -0
  28. package/dist/cli/data-render.js.map +1 -0
  29. package/dist/cli/doctor.js +7 -3
  30. package/dist/cli/doctor.js.map +1 -1
  31. package/dist/cli/index.js +757 -26
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/cli/live-render.d.ts +24 -0
  34. package/dist/cli/live-render.js +85 -0
  35. package/dist/cli/live-render.js.map +1 -0
  36. package/dist/cli/range.d.ts +28 -0
  37. package/dist/cli/range.js +63 -0
  38. package/dist/cli/range.js.map +1 -0
  39. package/dist/cli/render.js +3 -0
  40. package/dist/cli/render.js.map +1 -1
  41. package/dist/cli/strategy-render.d.ts +36 -0
  42. package/dist/cli/strategy-render.js +391 -0
  43. package/dist/cli/strategy-render.js.map +1 -0
  44. package/dist/cli/width.d.ts +18 -0
  45. package/dist/cli/width.js +71 -0
  46. package/dist/cli/width.js.map +1 -0
  47. package/dist/config/loader.js +1 -1
  48. package/dist/config/schema.d.ts +7 -0
  49. package/dist/config/schema.js +24 -0
  50. package/dist/config/schema.js.map +1 -1
  51. package/dist/core/okx-client.d.ts +9 -1
  52. package/dist/core/okx-client.js +14 -5
  53. package/dist/core/okx-client.js.map +1 -1
  54. package/dist/i18n/locale.d.ts +24 -0
  55. package/dist/i18n/locale.js +65 -0
  56. package/dist/i18n/locale.js.map +1 -0
  57. package/dist/i18n/messages.d.ts +333 -0
  58. package/dist/i18n/messages.js +660 -0
  59. package/dist/i18n/messages.js.map +1 -0
  60. package/dist/live/account-snapshot.d.ts +30 -0
  61. package/dist/live/account-snapshot.js +130 -0
  62. package/dist/live/account-snapshot.js.map +1 -0
  63. package/dist/live/cutoff-queue.d.ts +42 -0
  64. package/dist/live/cutoff-queue.js +69 -0
  65. package/dist/live/cutoff-queue.js.map +1 -0
  66. package/dist/live/execution-key.d.ts +23 -0
  67. package/dist/live/execution-key.js +31 -0
  68. package/dist/live/execution-key.js.map +1 -0
  69. package/dist/live/failures.d.ts +37 -0
  70. package/dist/live/failures.js +57 -0
  71. package/dist/live/failures.js.map +1 -0
  72. package/dist/live/gates.d.ts +65 -0
  73. package/dist/live/gates.js +136 -0
  74. package/dist/live/gates.js.map +1 -0
  75. package/dist/live/loop.d.ts +56 -0
  76. package/dist/live/loop.js +197 -0
  77. package/dist/live/loop.js.map +1 -0
  78. package/dist/live/preconditions.d.ts +48 -0
  79. package/dist/live/preconditions.js +69 -0
  80. package/dist/live/preconditions.js.map +1 -0
  81. package/dist/live/reconcile.d.ts +46 -0
  82. package/dist/live/reconcile.js +104 -0
  83. package/dist/live/reconcile.js.map +1 -0
  84. package/dist/live/runner.d.ts +57 -0
  85. package/dist/live/runner.js +160 -0
  86. package/dist/live/runner.js.map +1 -0
  87. package/dist/live/schema.d.ts +18 -0
  88. package/dist/live/schema.js +91 -0
  89. package/dist/live/schema.js.map +1 -0
  90. package/dist/live/service.d.ts +144 -0
  91. package/dist/live/service.js +303 -0
  92. package/dist/live/service.js.map +1 -0
  93. package/dist/live/session.d.ts +85 -0
  94. package/dist/live/session.js +234 -0
  95. package/dist/live/session.js.map +1 -0
  96. package/dist/live/sizing.d.ts +62 -0
  97. package/dist/live/sizing.js +79 -0
  98. package/dist/live/sizing.js.map +1 -0
  99. package/dist/live/store.d.ts +123 -0
  100. package/dist/live/store.js +350 -0
  101. package/dist/live/store.js.map +1 -0
  102. package/dist/live/types.d.ts +82 -0
  103. package/dist/live/types.js +2 -0
  104. package/dist/live/types.js.map +1 -0
  105. package/dist/market/websocket.d.ts +16 -1
  106. package/dist/market/websocket.js +60 -5
  107. package/dist/market/websocket.js.map +1 -1
  108. package/dist/mcp/server.d.ts +1 -0
  109. package/dist/mcp/server.js +15 -1
  110. package/dist/mcp/server.js.map +1 -1
  111. package/dist/network/connectivity.d.ts +9 -1
  112. package/dist/network/connectivity.js +28 -1
  113. package/dist/network/connectivity.js.map +1 -1
  114. package/dist/report/chart-script.d.ts +12 -0
  115. package/dist/report/chart-script.js +146 -0
  116. package/dist/report/chart-script.js.map +1 -0
  117. package/dist/report/compare-html.d.ts +8 -0
  118. package/dist/report/compare-html.js +254 -0
  119. package/dist/report/compare-html.js.map +1 -0
  120. package/dist/report/compare-script.d.ts +12 -0
  121. package/dist/report/compare-script.js +109 -0
  122. package/dist/report/compare-script.js.map +1 -0
  123. package/dist/report/compare.d.ts +61 -0
  124. package/dist/report/compare.js +205 -0
  125. package/dist/report/compare.js.map +1 -0
  126. package/dist/report/fetch.d.ts +20 -0
  127. package/dist/report/fetch.js +56 -0
  128. package/dist/report/fetch.js.map +1 -0
  129. package/dist/report/html.d.ts +54 -0
  130. package/dist/report/html.js +641 -0
  131. package/dist/report/html.js.map +1 -0
  132. package/dist/report/open.d.ts +42 -0
  133. package/dist/report/open.js +114 -0
  134. package/dist/report/open.js.map +1 -0
  135. package/dist/runtime/server.d.ts +16 -1
  136. package/dist/runtime/server.js +112 -9
  137. package/dist/runtime/server.js.map +1 -1
  138. package/dist/setup/installer.d.ts +1 -0
  139. package/dist/setup/installer.js +8 -0
  140. package/dist/setup/installer.js.map +1 -1
  141. package/dist/setup/wizard.js +19 -22
  142. package/dist/setup/wizard.js.map +1 -1
  143. package/dist/strategy/constants.d.ts +23 -0
  144. package/dist/strategy/constants.js +24 -0
  145. package/dist/strategy/constants.js.map +1 -0
  146. package/dist/strategy/environment.d.ts +52 -0
  147. package/dist/strategy/environment.js +187 -0
  148. package/dist/strategy/environment.js.map +1 -0
  149. package/dist/strategy/instrument.d.ts +29 -0
  150. package/dist/strategy/instrument.js +39 -0
  151. package/dist/strategy/instrument.js.map +1 -0
  152. package/dist/strategy/optimize.d.ts +73 -0
  153. package/dist/strategy/optimize.js +113 -0
  154. package/dist/strategy/optimize.js.map +1 -0
  155. package/dist/strategy/parameter-space.d.ts +59 -0
  156. package/dist/strategy/parameter-space.js +221 -0
  157. package/dist/strategy/parameter-space.js.map +1 -0
  158. package/dist/strategy/python-bridge.d.ts +24 -0
  159. package/dist/strategy/python-bridge.js +114 -0
  160. package/dist/strategy/python-bridge.js.map +1 -0
  161. package/dist/strategy/schema.d.ts +9 -0
  162. package/dist/strategy/schema.js +91 -0
  163. package/dist/strategy/schema.js.map +1 -0
  164. package/dist/strategy/service.d.ts +138 -0
  165. package/dist/strategy/service.js +745 -0
  166. package/dist/strategy/service.js.map +1 -0
  167. package/dist/strategy/settings.d.ts +162 -0
  168. package/dist/strategy/settings.js +243 -0
  169. package/dist/strategy/settings.js.map +1 -0
  170. package/dist/strategy/store.d.ts +96 -0
  171. package/dist/strategy/store.js +367 -0
  172. package/dist/strategy/store.js.map +1 -0
  173. package/dist/strategy/templates.d.ts +11 -0
  174. package/dist/strategy/templates.js +134 -0
  175. package/dist/strategy/templates.js.map +1 -0
  176. package/dist/strategy/types.d.ts +111 -0
  177. package/dist/strategy/types.js +2 -0
  178. package/dist/strategy/types.js.map +1 -0
  179. package/dist/tools/catalog.d.ts +16 -0
  180. package/dist/tools/catalog.js +118 -17
  181. package/dist/tools/catalog.js.map +1 -1
  182. package/dist/trade/service.d.ts +12 -0
  183. package/dist/trade/service.js +24 -7
  184. package/dist/trade/service.js.map +1 -1
  185. package/dist/tui/app.d.ts +23 -0
  186. package/dist/tui/app.js +322 -0
  187. package/dist/tui/app.js.map +1 -0
  188. package/dist/tui/commands.d.ts +70 -0
  189. package/dist/tui/commands.js +313 -0
  190. package/dist/tui/commands.js.map +1 -0
  191. package/dist/tui/entries.d.ts +17 -0
  192. package/dist/tui/entries.js +24 -0
  193. package/dist/tui/entries.js.map +1 -0
  194. package/dist/tui/execute.d.ts +26 -0
  195. package/dist/tui/execute.js +664 -0
  196. package/dist/tui/execute.js.map +1 -0
  197. package/dist/tui/history.d.ts +17 -0
  198. package/dist/tui/history.js +48 -0
  199. package/dist/tui/history.js.map +1 -0
  200. package/dist/tui/index.d.ts +8 -0
  201. package/dist/tui/index.js +48 -0
  202. package/dist/tui/index.js.map +1 -0
  203. package/dist/tui/line-editor.d.ts +44 -0
  204. package/dist/tui/line-editor.js +98 -0
  205. package/dist/tui/line-editor.js.map +1 -0
  206. package/dist/tui/progress.d.ts +23 -0
  207. package/dist/tui/progress.js +46 -0
  208. package/dist/tui/progress.js.map +1 -0
  209. package/dist/tui/settings-editor.d.ts +18 -0
  210. package/dist/tui/settings-editor.js +115 -0
  211. package/dist/tui/settings-editor.js.map +1 -0
  212. package/docs/live-trading.md +455 -0
  213. package/docs/strategy-research.md +597 -0
  214. package/package.json +10 -1
  215. package/python/desic_strategy/__init__.py +34 -0
  216. package/python/desic_strategy/actions.py +158 -0
  217. package/python/desic_strategy/context.py +164 -0
  218. package/python/desic_strategy/engine.py +614 -0
  219. package/python/desic_strategy/indicators.py +159 -0
  220. package/python/desic_strategy/live.py +253 -0
  221. package/python/desic_strategy/policy.py +193 -0
  222. package/python/desic_strategy/portfolio.py +152 -0
  223. package/python/desic_strategy/report.py +319 -0
  224. package/python/desic_strategy/runner.py +574 -0
  225. package/python/desic_strategy/timeframe.py +150 -0
  226. package/python/main.py +18 -0
  227. package/skills/okx-live-trading/SKILL.md +117 -0
  228. package/skills/okx-live-trading/agents/openai.yaml +9 -0
  229. package/skills/okx-live-trading/references/lifecycle.md +128 -0
  230. package/skills/okx-strategy-research/SKILL.md +113 -0
  231. package/skills/okx-strategy-research/agents/openai.yaml +9 -0
  232. package/skills/okx-strategy-research/references/execution-semantics.md +107 -0
  233. package/skills/okx-strategy-research/references/field-traps.md +142 -0
  234. package/skills/okx-strategy-research/references/python-api.md +121 -0
  235. package/skills/okx-strategy-research/references/tools-and-data.md +192 -0
  236. package/skills/okx-trading/SKILL.md +11 -10
package/README.en.md CHANGED
@@ -7,6 +7,9 @@ An independent local OKX Runtime, MCP server, CLI, and reusable agent Skills for
7
7
  > [!IMPORTANT]
8
8
  > Desic OKX Agent is an independent community project. It is not affiliated with, endorsed by, or an official product of OKX.
9
9
 
10
+ > [!NOTE]
11
+ > All trading tools in this project support OKX perpetual swaps only (`instId` must end in `-SWAP`). Spot, dated futures, options, and all other instrument types are not supported for trading. Public market data and account inspection are unaffected.
12
+
10
13
  ## Installation
11
14
 
12
15
  Requires Node.js 22.12 or newer and network access to OKX, either directly or through an HTTP/HTTPS proxy.
@@ -37,10 +40,10 @@ The interactive guide:
37
40
 
38
41
  1. Lets you select Codex, Claude Code, Cursor, VS Code / GitHub Copilot, Cline, or all clients.
39
42
  2. Registers the `desic-okx` MCP server without replacing existing MCP entries.
40
- 3. Installs all seven bundled Skills for Codex and Claude Code.
43
+ 3. Installs all nine bundled Skills for Codex and Claude Code.
41
44
  4. Checks OKX REST and WebSocket connectivity and guides you through testing and saving an HTTP proxy when needed.
42
45
  5. Explains which features require an API key and lets you configure one now or skip it.
43
- 6. Masks credential input, verifies the account with OKX, and saves it only after successful verification.
46
+ 6. Masks credential input, automatically detects Live or Demo Trading, and saves the account only after successful verification.
44
47
 
45
48
  An API account is optional. Public market and derivatives tools remain available when you skip this step. Configure an account later with:
46
49
 
@@ -59,7 +62,7 @@ desic-okx setup --targets codex --yes --skip-network-check
59
62
 
60
63
  ## Configure an OKX API account
61
64
 
62
- Create an API key in the official OKX website or app. Live and Demo Trading accounts use keys for their respective environments, so select the matching `live` or `demo` environment in the guide.
65
+ Create an API key in the official OKX website or app. Live and Demo Trading accounts use keys for their respective environments. Desic OKX Agent detects the environment through read-only verification, so the user does not select it.
63
66
 
64
67
  Grant only the permissions needed for your use case:
65
68
 
@@ -68,15 +71,15 @@ Grant only the permissions needed for your use case:
68
71
  | Public market data, candles, books, derivatives analysis | No | None |
69
72
  | Balances, positions, orders, fills, and risk summaries | Yes | Read permission |
70
73
  | Remote News and Smart Money | Yes | A `live` account; read permission is sufficient |
71
- | Place, amend, cancel, close, and leverage operations | Yes | Trade permission on the OKX API key |
74
+ | Perpetual swap place, amend, cancel, close, and leverage operations | Yes | Trade permission on the OKX API key; `*-SWAP` only |
72
75
 
73
76
  This project has no withdrawal, deposit, transfer, asset-movement, or API-key-management tools. Those permissions are not needed. Test trading workflows with an OKX Demo account first, and configure an IP allowlist in OKX according to your security policy.
74
77
 
75
78
  Add an account interactively:
76
79
 
77
80
  ```bash
78
- desic-okx account add --name demo --environment demo
79
- desic-okx account add --name main --environment live
81
+ desic-okx account add --name demo
82
+ desic-okx account add --name main
80
83
  ```
81
84
 
82
85
  API Key, Secret Key, and Passphrase input is hidden. `account add` verifies the credentials with OKX before writing them; failed verification saves nothing. Credentials are stored in `config.json` under the system configuration directory, with Unix permissions set to `0600`:
@@ -92,10 +95,9 @@ OKX_ACCOUNT
92
95
  OKX_API_KEY
93
96
  OKX_API_SECRET
94
97
  OKX_API_PASSPHRASE
95
- OKX_ENVIRONMENT=demo|live
96
98
  ```
97
99
 
98
- All three credential variables must be provided together. Trading availability is determined entirely by the permissions assigned to the API key in OKX.
100
+ All three credential variables must be provided together. The Runtime detects the account environment automatically. Trading availability is determined entirely by the permissions assigned to the API key in OKX.
99
101
 
100
102
  ## Ask an AI to install it
101
103
 
@@ -142,9 +144,85 @@ desic-okx update --check
142
144
  - Time-aligned decision snapshots with freshness, exchange timestamps, and consistency metadata
143
145
  - Public market data, indicators, scanning, and public derivatives analysis
144
146
  - Account balances, positions, orders, fills, bills, and risk summaries
145
- - Ordinary orders, algo orders, leverage, amend, cancel, and close-position operations
147
+ - Perpetual-swap-only ordinary orders, algo orders, leverage, amend, cancel, and close-position operations
146
148
  - Experimental News and Smart Money capabilities with SQLite history fallback
147
149
  - SQLite WAL persistence for closed candles, intelligence history, derived events, and execution records
150
+ - Python strategy research: one-minute history, backtests, parameter tuning, and run comparison
151
+ - Live execution: bind a backtested strategy to an account and act on every closed minute, behind eight risk gates
152
+
153
+ ## One chain, not two products
154
+
155
+ The capabilities above are not a flat list — they are segments of one chain. **Working by hand and
156
+ delegating to an AI follow the same chain:**
157
+
158
+ ```text
159
+ analyze ──→ write a strategy ──→ backtest ──→ tune ──→ create a profile ──→ verify on demo ──→ go live
160
+ market/derivatives Python 70/30 split rank on creating never real orders real
161
+ news/smart money source file validation starts trading money
162
+ (you approve)
163
+ ```
164
+
165
+ The only difference between the two is who presses the keys:
166
+
167
+ | | By hand | Delegated to an AI |
168
+ | --- | --- | --- |
169
+ | Find an idea | `market_*` / `news_*` tools, or the TUI | `okx-market-analysis` and related Skills |
170
+ | Write a strategy | `strategy new`, then edit it | the agent writes the file, `strategy_validate_source` checks it |
171
+ | Backtest and tune | `strategy backtest` / `optimize` / `compare` | the same MCP tools, plus the `okx-strategy-research` Skill |
172
+ | Create a profile | `live create` | `live_create_profile` (requires `agent-access`) |
173
+ | Enable live | `live start` | `live_start`, and the Skill requires **asking you first, with numbers** |
174
+
175
+ By default an agent can only read and stop; creating and enabling are absent from its tool list. To
176
+ let an AI run the whole chain:
177
+
178
+ ```bash
179
+ desic-okx live agent-access on # restart the MCP client to apply
180
+ desic-okx live agent-access # show the current setting
181
+ ```
182
+
183
+ Even then the Skill requires the agent to stop and ask before enabling a live profile — that
184
+ constraint lives in the Skill, not in a system gate. The system can verify whether a profile *can*
185
+ run; it cannot verify whether real money *should* be committed to it.
186
+
187
+ ## Strategy research
188
+
189
+ Write strategies in Python and backtest, tune, and compare them against local
190
+ one-minute history:
191
+
192
+ ```bash
193
+ desic-okx strategy env --setup
194
+ desic-okx data download --inst BTC-USDT-SWAP --days 90
195
+ desic-okx strategy new --out ema.py --template ema-trend
196
+ desic-okx strategy backtest --file ema.py --inst BTC-USDT-SWAP --days 30 --follow
197
+ ```
198
+
199
+ Tuning splits the window 70/30 and ranks candidates on the part they never saw, so
200
+ overfitting is visible rather than buried. Comparison warns when two runs used
201
+ different data, instruments, windows, or costs.
202
+
203
+ Full guide: **[docs/strategy-research.md](docs/strategy-research.md)** (Chinese).
204
+
205
+ ## Live execution
206
+
207
+ Run a validated strategy against a real account, acting on every closed minute:
208
+
209
+ ```bash
210
+ desic-okx live create --file ema.py --inst BTC-USDT-SWAP --account demo \
211
+ --environment demo --entry-budget 100 --side-budget 200 --daily-loss 500
212
+ desic-okx live readiness --id lp_xxxx
213
+ desic-okx live start --id lp_xxxx
214
+ desic-okx live signals --id lp_xxxx
215
+ ```
216
+
217
+ Enabling requires a completed backtest of that exact source on that exact instrument, matched by
218
+ source hash rather than filename, and writes the profile's leverage to the exchange — the entry
219
+ budget is sized against that figure, so a mismatch makes the budget mean something else. Eight risk
220
+ gates refuse rather than adjust, and every refusal is kept — those rows are the evidence risk
221
+ control ran. After a crash, unresolved signals are reconciled against the exchange and never
222
+ resubmitted.
223
+
224
+ **This places real orders.** Full guide: **[docs/live-trading.md](docs/live-trading.md)**
225
+ (Chinese).
148
226
 
149
227
  ## Skills
150
228
 
@@ -156,6 +234,8 @@ desic-okx update --check
156
234
  - `okx-smart-money-analysis`
157
235
  - `okx-account-analysis`
158
236
  - `okx-trading`
237
+ - `okx-strategy-research`
238
+ - `okx-live-trading`
159
239
  - `trading-philosophy`
160
240
 
161
241
  Skills are synchronized after upgrades. You can also inspect or synchronize them manually; modified copies are backed up first:
@@ -268,6 +348,6 @@ Trading software can cause financial loss. This project provides no investment a
268
348
 
269
349
  ## Status and license
270
350
 
271
- This is pre-release software at version `0.2.1`. OKX Demo trading should be validated in the target network environment before a `1.0.0` release.
351
+ This is pre-release software at version `0.3.0`. OKX Demo trading should be validated in the target network environment before a `1.0.0` release. Strategy research and live execution have been verified end to end on the OKX demo venue; **live execution has not yet run against real money over any length of time**.
272
352
 
273
353
  MIT License. See `LICENSE`. OKX and related marks belong to their respective owners.
package/README.md CHANGED
@@ -7,6 +7,9 @@
7
7
  > [!IMPORTANT]
8
8
  > Desic OKX Agent 是独立的社区项目,并非 OKX 官方产品,也未获得 OKX 的认可或背书。
9
9
 
10
+ > [!NOTE]
11
+ > 本项目的所有交易工具仅支持 OKX 永续合约(`instId` 必须以 `-SWAP` 结尾)。不支持现货、交割合约、期权或其他品种的交易。公共行情和账户查询不受此限制。
12
+
10
13
  ## 安装
11
14
 
12
15
  要求 Node.js 22.12 或更高版本,以及能够访问 OKX 的网络或 HTTP/HTTPS 代理。
@@ -37,10 +40,10 @@ desic-okx doctor
37
40
 
38
41
  1. 选择 Codex、Claude Code、Cursor、VS Code / GitHub Copilot、Cline,或全部客户端。
39
42
  2. 注册 `desic-okx` MCP Server,保留已有 MCP 配置。
40
- 3. 为 Codex 和 Claude Code 自动安装全部 7 个 Skills。
43
+ 3. 为 Codex 和 Claude Code 自动安装全部 9 个 Skills。
41
44
  4. 检查 OKX REST 与 WebSocket;连接失败时引导测试并保存 HTTP 代理。
42
45
  5. 解释不同功能的 API Key 要求,并让用户选择“现在配置”或“以后配置”。
43
- 6. 如果现在配置,隐藏凭证输入,先向 OKX 验证,成功后才写入本地配置。
46
+ 6. 如果现在配置,隐藏凭证输入,自动识别实盘或模拟盘,验证成功后才写入本地配置。
44
47
 
45
48
  API 账户是可选的。跳过后公共行情和公共衍生品仍可使用,以后运行下面的命令即可配置:
46
49
 
@@ -59,7 +62,7 @@ desic-okx setup --targets codex --yes --skip-network-check
59
62
 
60
63
  ## 配置 OKX API
61
64
 
62
- 在 OKX 官方网站或 App 中创建 API Key。实盘账户与模拟交易账户使用各自环境的 API Key;在向导中必须选择对应的 `live` `demo` 环境。
65
+ 在 OKX 官方网站或 App 中创建 API Key。实盘账户与模拟交易账户使用各自环境的 API Key,Desic OKX Agent 会通过只读验证自动识别,不需要用户选择实盘或模拟盘。
63
66
 
64
67
  按实际用途授予权限:
65
68
 
@@ -68,15 +71,15 @@ desic-okx setup --targets codex --yes --skip-network-check
68
71
  | 公共行情、K 线、盘口、衍生品分析 | 否 | 无 |
69
72
  | 余额、持仓、订单、成交、风险摘要 | 是 | 读取权限 |
70
73
  | 远程 News、Smart Money | 是 | `live` 账户,读取权限即可 |
71
- | 下单、改单、撤单、平仓、设置杠杆 | 是 | OKX API Key 具备交易权限 |
74
+ | 永续合约下单、改单、撤单、平仓、设置杠杆 | 是 | OKX API Key 具备交易权限;仅支持 `*-SWAP` |
72
75
 
73
76
  本项目不提供提现、充值、资金划转、资产转出或 API Key 管理工具,不需要为此授予相关权限。建议先使用 OKX 模拟交易账户验证交易流程,并按自己的安全策略在 OKX 配置 IP 白名单。
74
77
 
75
78
  交互式添加账户:
76
79
 
77
80
  ```bash
78
- desic-okx account add --name demo --environment demo
79
- desic-okx account add --name main --environment live
81
+ desic-okx account add --name demo
82
+ desic-okx account add --name main
80
83
  ```
81
84
 
82
85
  输入 API Key、Secret Key 和 Passphrase 时终端会隐藏文本。`account add` 会先连接 OKX 验证,验证失败不会保存凭证。凭证保存在系统配置目录的 `config.json` 中;Unix 权限为 `0600`:
@@ -92,10 +95,9 @@ OKX_ACCOUNT
92
95
  OKX_API_KEY
93
96
  OKX_API_SECRET
94
97
  OKX_API_PASSPHRASE
95
- OKX_ENVIRONMENT=demo|live
96
98
  ```
97
99
 
98
- 三个凭证变量必须同时提供。能否交易完全取决于 OKX 为该 API Key 配置的官方权限。
100
+ 三个凭证变量必须同时提供。Runtime 会自动探测账户环境;能否交易完全取决于 OKX 为该 API Key 配置的官方权限。
99
101
 
100
102
  ## 让 AI 自动安装
101
103
 
@@ -142,9 +144,71 @@ desic-okx update --check
142
144
  - 带新鲜度、交易所时间和一致性元数据的统一决策快照
143
145
  - 公共行情、指标扫描和公共衍生品分析
144
146
  - 账户余额、持仓、委托、成交、账单及风险摘要
145
- - 普通单、策略单、杠杆、改单、撤单和平仓操作
147
+ - 仅限永续合约的普通单、策略单、杠杆、改单、撤单和平仓操作
146
148
  - 实验性的 News 与 Smart Money 能力,以及 SQLite 历史回退
147
149
  - SQLite WAL 持久化已收盘 K 线、情报历史、派生事件和执行记录
150
+ - Python 策略研究:1 分钟历史数据、回测、参数调优、多次回测对比
151
+ - 实盘执行:把已回测的策略绑到账户,每根 1 分钟收线自动决策,八道风控闸门前置
152
+
153
+ ## 一条链,不是两个产品
154
+
155
+ 上面的能力不是并列的清单,而是同一条链上的几段。**手动做和让 AI 做,走的是同一条链**:
156
+
157
+ ```text
158
+ 分析行情 ──→ 写成策略 ──→ 回测 ──→ 调参 ──→ 建 Profile ──→ 模拟盘验证 ──→ 实盘
159
+ 行情/衍生品 Python 7:3 切分 验证段排名 不会开始交易 真实下单 真钱
160
+ News/资金流 策略文件 (需你同意)
161
+ ```
162
+
163
+ 两种用法的区别只在谁按键:
164
+
165
+ | | 你自己做 | 交给 AI |
166
+ | --- | --- | --- |
167
+ | 找想法 | `market_*` / `news_*` 工具,或 TUI | `okx-market-analysis` 等 Skill |
168
+ | 写策略 | `strategy new` 起模板,自己编辑 | agent 写文件,`strategy_validate_source` 校验 |
169
+ | 回测调参 | `strategy backtest` / `optimize` / `compare` | 同名 MCP 工具,`okx-strategy-research` Skill |
170
+ | 建 Profile | `live create` | `live_create_profile`(需开 `agent-access`) |
171
+ | 启用实盘 | `live start` | `live_start`,且 Skill 要求**先问你并给出数字** |
172
+
173
+ 默认情况下 agent 只能读和停,创建与启用不在它的工具列表里。要让 AI 跑完整条链:
174
+
175
+ ```bash
176
+ desic-okx live agent-access on # 需重启 MCP 客户端
177
+ desic-okx live agent-access # 查看当前设置
178
+ ```
179
+
180
+ 开启后 agent 仍被要求在启用实盘 Profile 前停下来问你 —— 这条约束写在 Skill 里,不是系统闸门。系统能验证的是"这个 Profile 能不能跑",不能验证"该不该投真钱"。
181
+
182
+ ## 策略研究
183
+
184
+ 用 Python 写策略,在本地 1 分钟历史数据上回测、调参、对比:
185
+
186
+ ```bash
187
+ desic-okx strategy env --setup
188
+ desic-okx data download --inst BTC-USDT-SWAP --days 90
189
+ desic-okx strategy new --out ema.py --template ema-trend
190
+ desic-okx strategy backtest --file ema.py --inst BTC-USDT-SWAP --days 30 --follow
191
+ ```
192
+
193
+ 调参会把窗口按 7:3 切分,用候选从未见过的那一段排名,因此过拟合是可见的而不是被埋掉的。对比会在两次运行数据、合约、区间或成本不同时给出警告。
194
+
195
+ 完整说明见 **[策略研究使用指南](docs/strategy-research.md)**。
196
+
197
+ ## 实盘执行
198
+
199
+ 把已验证的策略接到真实账户,每根 1 分钟收线自动执行:
200
+
201
+ ```bash
202
+ desic-okx live create --file ema.py --inst BTC-USDT-SWAP --account demo \
203
+ --environment demo --entry-budget 100 --side-budget 200 --daily-loss 500
204
+ desic-okx live readiness --id lp_xxxx
205
+ desic-okx live start --id lp_xxxx
206
+ desic-okx live signals --id lp_xxxx
207
+ ```
208
+
209
+ 启用需要该源码 + 该合约已完成回测(按源码 hash 匹配,不是文件名),并会把 Profile 的杠杆写到交易所 —— 预算按杠杆折算张数,两边不一致预算就不成立。八道风控闸门只拒绝、不修正,被拒绝的信号会完整保留 —— 它们是风控运行过的证据。崩溃后向交易所对账,绝不重发可能已存在的订单。
210
+
211
+ **这部分会用真钱下单。** 完整说明与限制见 **[实盘执行使用指南](docs/live-trading.md)**。
148
212
 
149
213
  ## Skills
150
214
 
@@ -156,6 +220,8 @@ desic-okx update --check
156
220
  - `okx-smart-money-analysis`
157
221
  - `okx-account-analysis`
158
222
  - `okx-trading`
223
+ - `okx-strategy-research`
224
+ - `okx-live-trading`
159
225
  - `trading-philosophy`
160
226
 
161
227
  升级后 Skills 会自动同步。也可手动检查或同步;被修改的旧版本会先备份:
@@ -268,6 +334,6 @@ npm link
268
334
 
269
335
  ## 状态与许可
270
336
 
271
- 当前为 `0.2.1` 预发布版本。正式发布 `1.0.0` 前,应在目标网络环境中完成 OKX Demo 交易验证。
337
+ 当前为 `0.3.0` 预发布版本。正式发布 `1.0.0` 前,应在目标网络环境中完成 OKX Demo 交易验证。策略研究与实盘执行已在 OKX 模拟盘上端到端验证过,**实盘执行尚未经过长期真钱运行**。
272
338
 
273
339
  MIT License,详见 `LICENSE`。OKX 及相关商标归其各自权利人所有。
@@ -2,6 +2,7 @@ import crypto from "node:crypto";
2
2
  import WebSocket from "ws";
3
3
  import { HttpsProxyAgent } from "https-proxy-agent";
4
4
  import { resolveProxy } from "../network/proxy.js";
5
+ import { privateWsUrl } from "../network/connectivity.js";
5
6
  export class PrivateAccountWebSockets {
6
7
  store;
7
8
  connections;
@@ -43,10 +44,9 @@ export class PrivateAccountWebSockets {
43
44
  connect(connection) {
44
45
  if (connection.stopping)
45
46
  return;
46
- const url = connection.account.environment === "demo"
47
- ? "wss://wspap.okx.com:8443/ws/v5/private"
48
- : "wss://ws.okx.com:8443/ws/v5/private";
49
- const socket = new WebSocket(url, this.agent ? { agent: this.agent } : undefined);
47
+ // Per account, not per runtime: the private feed follows whichever environment
48
+ // the credentials belong to, while market data follows its own setting.
49
+ const socket = new WebSocket(privateWsUrl(connection.account.environment), this.agent ? { agent: this.agent } : undefined);
50
50
  connection.socket = socket;
51
51
  connection.authenticated = false;
52
52
  socket.on("open", () => socket.send(JSON.stringify({ op: "login", args: [loginArgs(connection.account)] })));
@@ -1 +1 @@
1
- {"version":3,"file":"private-websocket.js","sourceRoot":"","sources":["../../src/account/private-websocket.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"private-websocket.js","sourceRoot":"","sources":["../../src/account/private-websocket.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { RuntimeConfig } from "../config/schema.js";
2
2
  import { OkxClient } from "../core/okx-client.js";
3
- import { type AccountCredentials, type ToolResult } from "../core/types.js";
3
+ import { type AccountCredentials, type OkxEnvironment, type ToolResult } from "../core/types.js";
4
4
  import type { AccountStore } from "./store.js";
5
5
  export declare class AccountService {
6
6
  private readonly config;
@@ -20,3 +20,14 @@ export declare class AccountService {
20
20
  getRisk(name?: string): Promise<ToolResult<Record<string, unknown>>>;
21
21
  private wrap;
22
22
  }
23
+ export interface UnclassifiedAccountCredentials {
24
+ name: string;
25
+ apiKey: string;
26
+ secretKey: string;
27
+ passphrase: string;
28
+ }
29
+ export interface DetectedAccount {
30
+ account: AccountCredentials;
31
+ config: Record<string, unknown>;
32
+ }
33
+ export declare function detectAccountEnvironment(client: Pick<OkxClient, "privateGet">, credentials: UnclassifiedAccountCredentials, preferred?: OkxEnvironment): Promise<DetectedAccount>;
@@ -1,4 +1,5 @@
1
1
  import { resolveAccount } from "../config/loader.js";
2
+ import { RuntimeError } from "../core/errors.js";
2
3
  import { resultMeta } from "../core/types.js";
3
4
  export class AccountService {
4
5
  config;
@@ -108,6 +109,23 @@ export class AccountService {
108
109
  };
109
110
  }
110
111
  }
112
+ export async function detectAccountEnvironment(client, credentials, preferred) {
113
+ const environments = preferred === "demo" ? ["demo", "live"] : ["live", "demo"];
114
+ let lastError;
115
+ for (const environment of environments) {
116
+ const account = { ...credentials, environment };
117
+ try {
118
+ const [config] = await client.privateGet("/api/v5/account/config", account);
119
+ return { account, config: config ?? {} };
120
+ }
121
+ catch (error) {
122
+ lastError = error;
123
+ if (error instanceof RuntimeError && !["AUTH", "PERMISSION", "OKX_REJECTED"].includes(error.code))
124
+ throw error;
125
+ }
126
+ }
127
+ throw lastError ?? new RuntimeError("AUTH", "OKX account environment could not be detected");
128
+ }
111
129
  function recent(value) {
112
130
  return value && Date.now() - value.receivedAt <= 15_000 ? value : undefined;
113
131
  }
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/account/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/account/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export declare class PublicRestLimiter {
2
+ private readonly maxConcurrent;
3
+ private readonly now;
4
+ private readonly sleep;
5
+ private readonly buckets;
6
+ private active;
7
+ private readonly waiting;
8
+ constructor(maxConcurrent?: number, now?: () => number, sleep?: (ms: number) => Promise<void>);
9
+ /**
10
+ * Runs `task` once a concurrency slot is free and the endpoint's minimum
11
+ * spacing has elapsed. The slot is always released, so a rejected task
12
+ * cannot wedge the limiter.
13
+ */
14
+ run<T>(path: string, task: () => Promise<T>): Promise<T>;
15
+ private acquire;
16
+ private release;
17
+ private waitForBucket;
18
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Minimum spacing and concurrency ceiling for OKX public REST reads.
3
+ *
4
+ * A full backfill issues thousands of `history-candles` pages back to back,
5
+ * which trips OKX rate limiting long before it finishes. These values are the
6
+ * ones that proved stable in production use of the desktop terminal: spacing
7
+ * is applied per endpoint bucket, and a global semaphore caps concurrency
8
+ * across all buckets.
9
+ */
10
+ const DEFAULT_MIN_INTERVAL_MS = 80;
11
+ const MARKET_CANDLES_MIN_INTERVAL_MS = 60;
12
+ const HISTORY_CANDLES_MIN_INTERVAL_MS = 120;
13
+ const MAX_CONCURRENT = 4;
14
+ export class PublicRestLimiter {
15
+ maxConcurrent;
16
+ now;
17
+ sleep;
18
+ buckets = new Map();
19
+ active = 0;
20
+ waiting = [];
21
+ constructor(maxConcurrent = MAX_CONCURRENT, now = Date.now, sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))) {
22
+ this.maxConcurrent = maxConcurrent;
23
+ this.now = now;
24
+ this.sleep = sleep;
25
+ }
26
+ /**
27
+ * Runs `task` once a concurrency slot is free and the endpoint's minimum
28
+ * spacing has elapsed. The slot is always released, so a rejected task
29
+ * cannot wedge the limiter.
30
+ */
31
+ async run(path, task) {
32
+ await this.acquire();
33
+ try {
34
+ await this.waitForBucket(path);
35
+ return await task();
36
+ }
37
+ finally {
38
+ this.release();
39
+ }
40
+ }
41
+ async acquire() {
42
+ if (this.active < this.maxConcurrent) {
43
+ this.active += 1;
44
+ return;
45
+ }
46
+ await new Promise((resolve) => this.waiting.push(resolve));
47
+ this.active += 1;
48
+ }
49
+ release() {
50
+ this.active -= 1;
51
+ const next = this.waiting.shift();
52
+ if (next)
53
+ next();
54
+ }
55
+ async waitForBucket(path) {
56
+ const key = bucketKey(path);
57
+ const minIntervalMs = minIntervalFor(key);
58
+ const bucket = this.buckets.get(key) ?? { minIntervalMs, nextAllowedAt: 0 };
59
+ const now = this.now();
60
+ // Reserve this bucket's slot before awaiting so concurrent callers queue
61
+ // behind each other instead of all reading the same stale timestamp.
62
+ const startAt = Math.max(now, bucket.nextAllowedAt);
63
+ bucket.nextAllowedAt = startAt + minIntervalMs;
64
+ this.buckets.set(key, bucket);
65
+ const delay = startAt - now;
66
+ if (delay > 0)
67
+ await this.sleep(delay);
68
+ }
69
+ }
70
+ function bucketKey(path) {
71
+ if (path.startsWith("/api/v5/market/history-candles"))
72
+ return "history-candles";
73
+ if (path.startsWith("/api/v5/market/candles"))
74
+ return "candles";
75
+ return "default";
76
+ }
77
+ function minIntervalFor(key) {
78
+ if (key === "history-candles")
79
+ return HISTORY_CANDLES_MIN_INTERVAL_MS;
80
+ if (key === "candles")
81
+ return MARKET_CANDLES_MIN_INTERVAL_MS;
82
+ return DEFAULT_MIN_INTERVAL_MS;
83
+ }
84
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/bars/rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Strategy-research storage schema.
3
+ *
4
+ * Only confirmed one-minute bars are persisted. Every higher timeframe is
5
+ * derived by aggregating this single source, so a backtest and a live
6
+ * evaluation can never disagree about a bucket boundary.
7
+ *
8
+ * Prices are stored as TEXT exactly as OKX returned them. Parsing them into
9
+ * IEEE-754 doubles before storage would make `dataHash` unstable across
10
+ * platforms and would silently lose precision that the exchange reported.
11
+ */
12
+ export declare const BAR_SCHEMA_SQL = "\nCREATE TABLE IF NOT EXISTS bars_1m (\n -- demo | live. Part of the key because the two are separate matching venues with\n -- separate feeds: the same instrument and minute genuinely has different OHLCV in\n -- each, so one row per (environment, instrument, minute) is the only way both can\n -- be stored without one overwriting the other.\n environment TEXT NOT NULL DEFAULT 'live',\n inst_id TEXT NOT NULL,\n open_time INTEGER NOT NULL,\n close_time INTEGER NOT NULL,\n open TEXT NOT NULL,\n high TEXT NOT NULL,\n low TEXT NOT NULL,\n close TEXT NOT NULL,\n volume TEXT NOT NULL,\n source TEXT NOT NULL,\n updated_at INTEGER NOT NULL,\n PRIMARY KEY(environment, inst_id, open_time)\n) WITHOUT ROWID;\n\nCREATE TABLE IF NOT EXISTS bar_coverage (\n environment TEXT NOT NULL DEFAULT 'live',\n inst_id TEXT NOT NULL,\n oldest_open INTEGER NOT NULL,\n newest_open INTEGER NOT NULL,\n bar_count INTEGER NOT NULL,\n exhausted_before INTEGER,\n updated_at INTEGER NOT NULL,\n PRIMARY KEY(environment, inst_id)\n);\n\nCREATE TABLE IF NOT EXISTS bar_sync_runs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n environment TEXT NOT NULL DEFAULT 'live',\n inst_id TEXT NOT NULL,\n status TEXT NOT NULL,\n start_open INTEGER NOT NULL,\n end_open INTEGER NOT NULL,\n expected INTEGER NOT NULL,\n existing INTEGER NOT NULL,\n missing INTEGER NOT NULL,\n fetched INTEGER NOT NULL,\n inserted INTEGER NOT NULL,\n started_at INTEGER NOT NULL,\n finished_at INTEGER,\n message TEXT NOT NULL\n);\n\n";
13
+ /**
14
+ * Indexes that name the environment column.
15
+ *
16
+ * Applied after migration rather than with the tables above: on a pre-environment
17
+ * database the column does not exist yet, and `CREATE INDEX IF NOT EXISTS` still fails
18
+ * on an unknown column — which would abort the whole schema statement before the
19
+ * migration that adds it ever ran.
20
+ */
21
+ export declare const BAR_INDEX_SQL = "\nCREATE INDEX IF NOT EXISTS idx_bar_sync_runs_inst\n ON bar_sync_runs(environment, inst_id, started_at DESC);\n";
22
+ /**
23
+ * Adds the environment column to databases created before it existed.
24
+ *
25
+ * `bars_1m` and `bar_coverage` are keyed on it, and SQLite cannot add a column to an
26
+ * existing primary key, so those two are rebuilt. Existing rows become `live`, which
27
+ * is where they actually came from: demo is opt-in and nothing could have written
28
+ * demo bars before this column existed.
29
+ *
30
+ * Each rebuild runs in one transaction. A failure rolls back rather than leaving a
31
+ * half-migrated store, and the whole thing is a no-op once the column is present.
32
+ */
33
+ export declare const BAR_MIGRATION_STEPS: ReadonlyArray<{
34
+ table: string;
35
+ sql: string;
36
+ }>;