trading-cli 0.3.0__tar.gz → 0.3.1__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.
Files changed (71) hide show
  1. {trading_cli-0.3.0/trading_cli.egg-info → trading_cli-0.3.1}/PKG-INFO +23 -73
  2. {trading_cli-0.3.0 → trading_cli-0.3.1}/README.md +22 -72
  3. {trading_cli-0.3.0 → trading_cli-0.3.1}/SKILL.md +4 -3
  4. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/__init__.py +1 -1
  5. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/client.py +23 -2
  6. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/init_cmd.py +2 -0
  7. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/onchain.py +71 -0
  8. {trading_cli-0.3.0 → trading_cli-0.3.1}/pyproject.toml +1 -1
  9. {trading_cli-0.3.0 → trading_cli-0.3.1/trading_cli.egg-info}/PKG-INFO +23 -73
  10. {trading_cli-0.3.0 → trading_cli-0.3.1}/EXCHANGES.md +0 -0
  11. {trading_cli-0.3.0 → trading_cli-0.3.1}/LICENSE +0 -0
  12. {trading_cli-0.3.0 → trading_cli-0.3.1}/MANIFEST.in +0 -0
  13. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_alpaca.sh +0 -0
  14. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_binance.sh +0 -0
  15. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_bybit.sh +0 -0
  16. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_coinbase.sh +0 -0
  17. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_dex_perps.sh +0 -0
  18. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_hyperliquid.sh +0 -0
  19. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_ibkr.sh +0 -0
  20. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_kraken.sh +0 -0
  21. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_kucoin.sh +0 -0
  22. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/bots_okx.sh +0 -0
  23. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/forward_test_all.sh +0 -0
  24. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/paper_quickstart.sh +0 -0
  25. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/polymarket.sh +0 -0
  26. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/repl_session.sh +0 -0
  27. {trading_cli-0.3.0 → trading_cli-0.3.1}/examples/swaps_and_wallets.sh +0 -0
  28. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/__main__.py +0 -0
  29. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/__init__.py +0 -0
  30. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/apikey.py +0 -0
  31. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/backtest.py +0 -0
  32. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/bots.py +0 -0
  33. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/config.py +0 -0
  34. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/dex.py +0 -0
  35. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/direct.py +0 -0
  36. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/execution.py +0 -0
  37. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/markets.py +0 -0
  38. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/mcp_cmd.py +0 -0
  39. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/polymarket.py +0 -0
  40. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/repl.py +0 -0
  41. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/strategy.py +0 -0
  42. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/swap.py +0 -0
  43. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/commands/wallet.py +0 -0
  44. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/config_store.py +0 -0
  45. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/direct.py +0 -0
  46. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/main.py +0 -0
  47. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/mcp_server.py +0 -0
  48. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/output.py +0 -0
  49. {trading_cli-0.3.0 → trading_cli-0.3.1}/fastbooks_cli/strategies/__init__.py +0 -0
  50. {trading_cli-0.3.0 → trading_cli-0.3.1}/setup.cfg +0 -0
  51. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/README.md +0 -0
  52. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/__init__.py +0 -0
  53. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/conftest.py +0 -0
  54. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_backtest.py +0 -0
  55. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_bots_per_exchange.py +0 -0
  56. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_cli.py +0 -0
  57. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_dex.py +0 -0
  58. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_e2e_flows.py +0 -0
  59. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_execution_per_venue.py +0 -0
  60. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_paper_flows_per_exchange.py +0 -0
  61. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_polymarket.py +0 -0
  62. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_repl.py +0 -0
  63. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_strategy.py +0 -0
  64. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_stress.py +0 -0
  65. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_swap.py +0 -0
  66. {trading_cli-0.3.0 → trading_cli-0.3.1}/tests/test_wallet_creation.py +0 -0
  67. {trading_cli-0.3.0 → trading_cli-0.3.1}/trading_cli.egg-info/SOURCES.txt +0 -0
  68. {trading_cli-0.3.0 → trading_cli-0.3.1}/trading_cli.egg-info/dependency_links.txt +0 -0
  69. {trading_cli-0.3.0 → trading_cli-0.3.1}/trading_cli.egg-info/entry_points.txt +0 -0
  70. {trading_cli-0.3.0 → trading_cli-0.3.1}/trading_cli.egg-info/requires.txt +0 -0
  71. {trading_cli-0.3.0 → trading_cli-0.3.1}/trading_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trading-cli
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: Trade any exchange from the command line — agent-native trading CLI
5
5
  Author: FastBooks
6
6
  License: MIT
@@ -67,39 +67,42 @@ human-readable tables by default, machine-readable JSON with `--json`.
67
67
 
68
68
  ## Install
69
69
 
70
- Once published, it's a one-liner:
70
+ One-liner:
71
71
 
72
72
  ```bash
73
- pipx install fastbooks-cli # recommended (isolated); or: pip install fastbooks-cli
73
+ pipx install "trading-cli[agent]" # recommended (isolated); base: pip install trading-cli
74
74
  fastbooks --help
75
75
  ```
76
76
 
77
- From a checkout (development):
77
+ `trading-cli` is the base client (`click` + `requests`). The `[agent]` extra adds `ccxt`
78
+ (100+ exchanges, standalone) and the MCP server. Commands installed: `fastbooks`, `trading`, `fastbooks-mcp`.
79
+ Requires Python ≥ 3.10.
78
80
 
79
- ```bash
80
- cd cli && pip install -e . # installs the `fastbooks` command
81
- ```
81
+ ## What runs where
82
82
 
83
- Requires Python 3.10. Runtime deps are just `click` and `requests`.
83
+ The pip package is a **thin client** it does **not** run FastBooks' servers. On *your*
84
+ machine it runs: the CLI, the standalone **`direct`** engine (ccxt — 100+ exchanges, keyless
85
+ public data + trading on *your own* keys, no backend needed), and the **MCP server**.
84
86
 
85
- ## Talking to the backend
87
+ The **FastBooks platform** (aggregated multi-asset data, unified execution, bots, signals) is a
88
+ **hosted service** — the CLI points at it **by default**, no setup needed:
86
89
 
87
- The CLI is a thin client over two HTTP services:
90
+ | Service | Default (hosted) | Override env var |
91
+ |---------|------------------|------------------|
92
+ | Routing API (markets, execution, keys) | `https://app.fastbooks.exchange` | `FASTBOOKS_ROUTING_URL` |
93
+ | Bots service (deploy, forward-test) | `https://app.fastbooks.exchange` | `FASTBOOKS_BOTS_URL` |
88
94
 
89
- | Service | Default | Env var |
90
- |---------|---------|---------|
91
- | Routing API (markets, execution, keys) | `http://localhost:3002` | `FASTBOOKS_ROUTING_URL` |
92
- | Bots service (deploy, forward-test) | `http://localhost:8003` | `FASTBOOKS_BOTS_URL` |
95
+ > The CLI already targets the hosted FastBooks API — you don't run those services yourself.
96
+ > Just mint a key (`fastbooks apikey create`, free) and set `FASTBOOKS_API_KEY`; platform data
97
+ > is **metered per key**. For trading you never send exchange keys to the server the CLI trades
98
+ > client-side via `direct` with your own keys. Self-hosting the backend? Override the env vars to
99
+ > `http://localhost:3002` / `:8003`.
93
100
 
94
101
  ```bash
95
- fastbooks config show # show resolved URLs
96
- fastbooks config doctor # ping both services
102
+ fastbooks config show # show resolved URLs + stored config
103
+ fastbooks config health # ping the hosted services
97
104
  ```
98
105
 
99
- Auth: FastBooks platform keys (`apikey`) are **fully self-service — no admin
100
- token**. The only token you may need is `FASTBOOKS_API_TOKEN` (a JWT), and only
101
- for storing exchange keys & saved backtests.
102
-
103
106
  ---
104
107
 
105
108
  ## Quickstart — the four core flows
@@ -254,56 +257,3 @@ FASTBOOKS_E2E=1 python3 -m pytest -q # live smoke against running service
254
257
 
255
258
  See [tests/README.md](tests/README.md). The capability suite asserts the CLI
256
259
  hits the correct backend endpoints (method + path + auth) for the four flows.
257
-
258
- ---
259
-
260
- ## Publishing to PyPI
261
-
262
- The package builds from `pyproject.toml` (PEP 621, setuptools backend) — no
263
- Poetry needed. One-time tooling:
264
-
265
- ```bash
266
- pip install --upgrade build twine
267
- ```
268
-
269
- Release steps (run from `cli/`):
270
-
271
- ```bash
272
- # 1. Bump the version in pyproject.toml (e.g. 0.2.0 -> 0.2.1)
273
- # 2. Build sdist + wheel into dist/
274
- python3 -m build
275
-
276
- # 3. Sanity-check the metadata
277
- twine check dist/*
278
-
279
- # 4. Upload to TestPyPI first (recommended), then verify the install
280
- twine upload --repository testpypi dist/*
281
- pipx install --index-url https://test.pypi.org/simple/ fastbooks-cli
282
-
283
- # 5. Upload to real PyPI
284
- twine upload dist/*
285
- ```
286
-
287
- Auth uses an API token (create at https://pypi.org/manage/account/token/). Put it in
288
- `~/.pypirc` or pass it as the password with username `__token__`:
289
-
290
- ```ini
291
- # ~/.pypirc
292
- [pypi]
293
- username = __token__
294
- password = pypi-AgEN...your-token...
295
- [testpypi]
296
- username = __token__
297
- password = pypi-AgEN...your-testpypi-token...
298
- ```
299
-
300
- Notes:
301
- - The project name `fastbooks-cli` must be free on PyPI (check
302
- https://pypi.org/project/fastbooks-cli/); the `fastbooks` command name is unaffected by that.
303
- - `MANIFEST.in` ships `README.md`, `SKILL.md`, `EXCHANGES.md`, `LICENSE`, and `examples/`
304
- in the sdist. Only the `fastbooks_cli` package is included — **no strategy logic**.
305
- - Each upload version is immutable; bump the version for every release.
306
- - For automated releases, use the PyPI **Trusted Publisher** (OIDC) GitHub Action
307
- instead of a long-lived token.
308
- - The proprietary `fastbooks-clistrategies` package is built the same way but
309
- published privately (or installed from a Git URL), never to public PyPI.
@@ -31,39 +31,42 @@ human-readable tables by default, machine-readable JSON with `--json`.
31
31
 
32
32
  ## Install
33
33
 
34
- Once published, it's a one-liner:
34
+ One-liner:
35
35
 
36
36
  ```bash
37
- pipx install fastbooks-cli # recommended (isolated); or: pip install fastbooks-cli
37
+ pipx install "trading-cli[agent]" # recommended (isolated); base: pip install trading-cli
38
38
  fastbooks --help
39
39
  ```
40
40
 
41
- From a checkout (development):
41
+ `trading-cli` is the base client (`click` + `requests`). The `[agent]` extra adds `ccxt`
42
+ (100+ exchanges, standalone) and the MCP server. Commands installed: `fastbooks`, `trading`, `fastbooks-mcp`.
43
+ Requires Python ≥ 3.10.
42
44
 
43
- ```bash
44
- cd cli && pip install -e . # installs the `fastbooks` command
45
- ```
45
+ ## What runs where
46
46
 
47
- Requires Python 3.10. Runtime deps are just `click` and `requests`.
47
+ The pip package is a **thin client** it does **not** run FastBooks' servers. On *your*
48
+ machine it runs: the CLI, the standalone **`direct`** engine (ccxt — 100+ exchanges, keyless
49
+ public data + trading on *your own* keys, no backend needed), and the **MCP server**.
48
50
 
49
- ## Talking to the backend
51
+ The **FastBooks platform** (aggregated multi-asset data, unified execution, bots, signals) is a
52
+ **hosted service** — the CLI points at it **by default**, no setup needed:
50
53
 
51
- The CLI is a thin client over two HTTP services:
54
+ | Service | Default (hosted) | Override env var |
55
+ |---------|------------------|------------------|
56
+ | Routing API (markets, execution, keys) | `https://app.fastbooks.exchange` | `FASTBOOKS_ROUTING_URL` |
57
+ | Bots service (deploy, forward-test) | `https://app.fastbooks.exchange` | `FASTBOOKS_BOTS_URL` |
52
58
 
53
- | Service | Default | Env var |
54
- |---------|---------|---------|
55
- | Routing API (markets, execution, keys) | `http://localhost:3002` | `FASTBOOKS_ROUTING_URL` |
56
- | Bots service (deploy, forward-test) | `http://localhost:8003` | `FASTBOOKS_BOTS_URL` |
59
+ > The CLI already targets the hosted FastBooks API — you don't run those services yourself.
60
+ > Just mint a key (`fastbooks apikey create`, free) and set `FASTBOOKS_API_KEY`; platform data
61
+ > is **metered per key**. For trading you never send exchange keys to the server the CLI trades
62
+ > client-side via `direct` with your own keys. Self-hosting the backend? Override the env vars to
63
+ > `http://localhost:3002` / `:8003`.
57
64
 
58
65
  ```bash
59
- fastbooks config show # show resolved URLs
60
- fastbooks config doctor # ping both services
66
+ fastbooks config show # show resolved URLs + stored config
67
+ fastbooks config health # ping the hosted services
61
68
  ```
62
69
 
63
- Auth: FastBooks platform keys (`apikey`) are **fully self-service — no admin
64
- token**. The only token you may need is `FASTBOOKS_API_TOKEN` (a JWT), and only
65
- for storing exchange keys & saved backtests.
66
-
67
70
  ---
68
71
 
69
72
  ## Quickstart — the four core flows
@@ -218,56 +221,3 @@ FASTBOOKS_E2E=1 python3 -m pytest -q # live smoke against running service
218
221
 
219
222
  See [tests/README.md](tests/README.md). The capability suite asserts the CLI
220
223
  hits the correct backend endpoints (method + path + auth) for the four flows.
221
-
222
- ---
223
-
224
- ## Publishing to PyPI
225
-
226
- The package builds from `pyproject.toml` (PEP 621, setuptools backend) — no
227
- Poetry needed. One-time tooling:
228
-
229
- ```bash
230
- pip install --upgrade build twine
231
- ```
232
-
233
- Release steps (run from `cli/`):
234
-
235
- ```bash
236
- # 1. Bump the version in pyproject.toml (e.g. 0.2.0 -> 0.2.1)
237
- # 2. Build sdist + wheel into dist/
238
- python3 -m build
239
-
240
- # 3. Sanity-check the metadata
241
- twine check dist/*
242
-
243
- # 4. Upload to TestPyPI first (recommended), then verify the install
244
- twine upload --repository testpypi dist/*
245
- pipx install --index-url https://test.pypi.org/simple/ fastbooks-cli
246
-
247
- # 5. Upload to real PyPI
248
- twine upload dist/*
249
- ```
250
-
251
- Auth uses an API token (create at https://pypi.org/manage/account/token/). Put it in
252
- `~/.pypirc` or pass it as the password with username `__token__`:
253
-
254
- ```ini
255
- # ~/.pypirc
256
- [pypi]
257
- username = __token__
258
- password = pypi-AgEN...your-token...
259
- [testpypi]
260
- username = __token__
261
- password = pypi-AgEN...your-testpypi-token...
262
- ```
263
-
264
- Notes:
265
- - The project name `fastbooks-cli` must be free on PyPI (check
266
- https://pypi.org/project/fastbooks-cli/); the `fastbooks` command name is unaffected by that.
267
- - `MANIFEST.in` ships `README.md`, `SKILL.md`, `EXCHANGES.md`, `LICENSE`, and `examples/`
268
- in the sdist. Only the `fastbooks_cli` package is included — **no strategy logic**.
269
- - Each upload version is immutable; bump the version for every release.
270
- - For automated releases, use the PyPI **Trusted Publisher** (OIDC) GitHub Action
271
- instead of a long-lived token.
272
- - The proprietary `fastbooks-clistrategies` package is built the same way but
273
- published privately (or installed from a Git URL), never to public PyPI.
@@ -279,9 +279,10 @@ fastbooks --json wallet create-evm
279
279
 
280
280
  | Variable | Description |
281
281
  |----------|-------------|
282
- | `FASTBOOKS_ROUTING_URL` | Routing API (default: `http://localhost:3002`) |
283
- | `FASTBOOKS_BOTS_URL` | Bots service (default: `http://localhost:8003`) |
284
- | `FASTBOOKS_API_TOKEN` | JWT for authenticated routes (exchange keys, saved backtests) |
282
+ | `FASTBOOKS_ROUTING_URL` | Routing API (default: `https://app.fastbooks.exchange`; self-host: `http://localhost:3002`) |
283
+ | `FASTBOOKS_BOTS_URL` | Bots service (default: `https://app.fastbooks.exchange`; self-host: `http://localhost:8003`) |
284
+ | `FASTBOOKS_API_KEY` | FastBooks data key (`fb_live_…`) sent as `x-api-key`, metered per key. Mint: `fastbooks apikey create` |
285
+ | `FASTBOOKS_API_TOKEN` | JWT for authenticated routes (exchange keys, saved backtests, onchain) |
285
286
  | `FASTBOOKS_EXPERIMENTAL` | Set to `1` to enable the `swap`/`dex`/`polymarket` groups |
286
287
  | `ALPACA_API_KEY` | Alpaca API key |
287
288
  | `ALPACA_API_SECRET` | Alpaca API secret |
@@ -1,3 +1,3 @@
1
1
  """FastBooks CLI — agent-native trading interface."""
2
2
 
3
- __version__ = "0.3.0"
3
+ __version__ = "0.3.1"
@@ -9,8 +9,10 @@ from typing import Any
9
9
 
10
10
  import requests
11
11
 
12
- DEFAULT_ROUTING_URL = "http://localhost:3002"
13
- DEFAULT_BOTS_URL = "http://localhost:8003"
12
+ # Public hosted FastBooks API (this is our server). External users get it out of the box;
13
+ # self-hosters/devs override with FASTBOOKS_ROUTING_URL / FASTBOOKS_BOTS_URL (e.g. http://localhost:3002).
14
+ DEFAULT_ROUTING_URL = "https://app.fastbooks.exchange"
15
+ DEFAULT_BOTS_URL = "https://app.fastbooks.exchange"
14
16
 
15
17
 
16
18
  def _stored_api_key() -> str | None:
@@ -342,6 +344,25 @@ class FastBooksClient:
342
344
  def onchain_live_stop(self, strategy_id: str) -> Any:
343
345
  return self.onchain_post("/api/exec/live/stop", {"strategyId": strategy_id})
344
346
 
347
+ # on-chain DEX swaps (real signing happens in the engine; keys stay in its local KeyStore)
348
+ def onchain_buy(self, dex: str, token_address: str, amount_sol: float, slippage_bps: int | None = None) -> Any:
349
+ body: dict[str, Any] = {"dex": dex, "tokenAddress": token_address, "amountSol": amount_sol}
350
+ if slippage_bps is not None:
351
+ body["slippageBps"] = slippage_bps
352
+ return self.onchain_post("/api/exec/buy", body)
353
+
354
+ def onchain_sell(self, dex: str, token_address: str, token_amount: str, slippage_bps: int | None = None) -> Any:
355
+ body: dict[str, Any] = {"dex": dex, "tokenAddress": token_address, "tokenAmount": str(token_amount)}
356
+ if slippage_bps is not None:
357
+ body["slippageBps"] = slippage_bps
358
+ return self.onchain_post("/api/exec/sell", body)
359
+
360
+ def onchain_evm_swap(self, chain: str, sell_token: str, buy_token: str, sell_amount: str, slippage_bps: int | None = None) -> Any:
361
+ body: dict[str, Any] = {"chain": chain, "sellToken": sell_token, "buyToken": buy_token, "sellAmount": str(sell_amount)}
362
+ if slippage_bps is not None:
363
+ body["slippageBps"] = slippage_bps
364
+ return self.onchain_post("/api/exec/evm", body)
365
+
345
366
  def fastbooks_api_key_info(self, api_key: str) -> dict:
346
367
  return self._get(self.routing_url, "/api/keys/me", headers={"x-api-key": api_key})
347
368
 
@@ -21,6 +21,8 @@ CATALOG = [
21
21
  ["binance", "bybit", "okx", "kraken", "coinbase", "kucoin", "bitget", "gate", "mexc", "htx"], "ccxt"),
22
22
  ("On-chain perps / DEX — via ccxt (hyperliquid/dydx/… use a wallet key as 'secret')",
23
23
  ["hyperliquid", "dydx", "paradex", "apex", "woofipro"], "ccxt"),
24
+ ("Options & derivatives — via ccxt",
25
+ ["deribit", "okx", "bybit"], "ccxt"),
24
26
  ("Stocks — FastBooks platform (connect: `fastbooks --token <JWT> wallet add ...`)",
25
27
  ["alpaca", "ibkr"], "platform"),
26
28
  ("Forex — FastBooks platform",
@@ -121,3 +121,74 @@ def stop_cmd(ctx: click.Context, strategy_id: str):
121
121
  except Exception as e: # noqa: BLE001
122
122
  emit_error(ctx, str(e))
123
123
  ctx.exit(1)
124
+
125
+
126
+ # ── DEX swaps (real on-chain execution; signing happens in the engine's KeyStore) ──
127
+
128
+ def _confirm_live(ctx, msg: str, yes: bool) -> None:
129
+ if not yes and not ctx.find_root().params.get("json_output"):
130
+ click.confirm(msg, abort=True)
131
+
132
+
133
+ @onchain.command("buy")
134
+ @click.argument("dex", type=click.Choice(["jupiter", "pumpfun"]))
135
+ @click.argument("token_address")
136
+ @click.argument("amount_sol", type=float)
137
+ @click.option("--slippage-bps", type=int, default=None)
138
+ @click.option("--yes", is_flag=True, help="Skip the real-funds confirmation.")
139
+ @click.pass_context
140
+ def buy_cmd(ctx, dex, token_address, amount_sol, slippage_bps, yes):
141
+ """DEX swap SOL -> token (Jupiter aggregator or Pump.fun) — REAL funds.
142
+
143
+ e.g. onchain buy jupiter <MINT> 0.05
144
+ """
145
+ client: FastBooksClient = ctx.obj
146
+ _confirm_live(ctx, f"LIVE swap: buy {amount_sol} SOL of {token_address[:8]}… via {dex}?", yes)
147
+ try:
148
+ emit(ctx, client.onchain_buy(dex, token_address, amount_sol, slippage_bps))
149
+ except Exception as e: # noqa: BLE001
150
+ emit_error(ctx, str(e))
151
+ ctx.exit(1)
152
+
153
+
154
+ @onchain.command("sell")
155
+ @click.argument("dex", type=click.Choice(["jupiter", "pumpfun"]))
156
+ @click.argument("token_address")
157
+ @click.argument("token_amount")
158
+ @click.option("--slippage-bps", type=int, default=None)
159
+ @click.option("--yes", is_flag=True, help="Skip the real-funds confirmation.")
160
+ @click.pass_context
161
+ def sell_cmd(ctx, dex, token_address, token_amount, slippage_bps, yes):
162
+ """DEX swap token -> SOL (Jupiter or Pump.fun) — REAL funds. token_amount is raw base units.
163
+
164
+ e.g. onchain sell jupiter <MINT> 413433846822
165
+ """
166
+ client: FastBooksClient = ctx.obj
167
+ _confirm_live(ctx, f"LIVE swap: sell {token_amount} of {token_address[:8]}… via {dex}?", yes)
168
+ try:
169
+ emit(ctx, client.onchain_sell(dex, token_address, token_amount, slippage_bps))
170
+ except Exception as e: # noqa: BLE001
171
+ emit_error(ctx, str(e))
172
+ ctx.exit(1)
173
+
174
+
175
+ @onchain.command("swap-evm")
176
+ @click.argument("chain", type=click.Choice(["arbitrum", "bsc"]))
177
+ @click.argument("sell_token")
178
+ @click.argument("buy_token")
179
+ @click.argument("sell_amount")
180
+ @click.option("--slippage-bps", type=int, default=None)
181
+ @click.option("--yes", is_flag=True, help="Skip the real-funds confirmation.")
182
+ @click.pass_context
183
+ def swap_evm_cmd(ctx, chain, sell_token, buy_token, sell_amount, slippage_bps, yes):
184
+ """EVM DEX swap via 0x (Uniswap-class) on arbitrum/bsc — REAL funds. sell_amount in base units.
185
+
186
+ e.g. onchain swap-evm arbitrum <USDC> <WETH> 1000000
187
+ """
188
+ client: FastBooksClient = ctx.obj
189
+ _confirm_live(ctx, f"LIVE swap on {chain}: {sell_amount} {sell_token[:8]}… -> {buy_token[:8]}…?", yes)
190
+ try:
191
+ emit(ctx, client.onchain_evm_swap(chain, sell_token, buy_token, sell_amount, slippage_bps))
192
+ except Exception as e: # noqa: BLE001
193
+ emit_error(ctx, str(e))
194
+ ctx.exit(1)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "trading-cli"
7
- version = "0.3.0"
7
+ version = "0.3.1"
8
8
  description = "Trade any exchange from the command line — agent-native trading CLI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: trading-cli
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: Trade any exchange from the command line — agent-native trading CLI
5
5
  Author: FastBooks
6
6
  License: MIT
@@ -67,39 +67,42 @@ human-readable tables by default, machine-readable JSON with `--json`.
67
67
 
68
68
  ## Install
69
69
 
70
- Once published, it's a one-liner:
70
+ One-liner:
71
71
 
72
72
  ```bash
73
- pipx install fastbooks-cli # recommended (isolated); or: pip install fastbooks-cli
73
+ pipx install "trading-cli[agent]" # recommended (isolated); base: pip install trading-cli
74
74
  fastbooks --help
75
75
  ```
76
76
 
77
- From a checkout (development):
77
+ `trading-cli` is the base client (`click` + `requests`). The `[agent]` extra adds `ccxt`
78
+ (100+ exchanges, standalone) and the MCP server. Commands installed: `fastbooks`, `trading`, `fastbooks-mcp`.
79
+ Requires Python ≥ 3.10.
78
80
 
79
- ```bash
80
- cd cli && pip install -e . # installs the `fastbooks` command
81
- ```
81
+ ## What runs where
82
82
 
83
- Requires Python 3.10. Runtime deps are just `click` and `requests`.
83
+ The pip package is a **thin client** it does **not** run FastBooks' servers. On *your*
84
+ machine it runs: the CLI, the standalone **`direct`** engine (ccxt — 100+ exchanges, keyless
85
+ public data + trading on *your own* keys, no backend needed), and the **MCP server**.
84
86
 
85
- ## Talking to the backend
87
+ The **FastBooks platform** (aggregated multi-asset data, unified execution, bots, signals) is a
88
+ **hosted service** — the CLI points at it **by default**, no setup needed:
86
89
 
87
- The CLI is a thin client over two HTTP services:
90
+ | Service | Default (hosted) | Override env var |
91
+ |---------|------------------|------------------|
92
+ | Routing API (markets, execution, keys) | `https://app.fastbooks.exchange` | `FASTBOOKS_ROUTING_URL` |
93
+ | Bots service (deploy, forward-test) | `https://app.fastbooks.exchange` | `FASTBOOKS_BOTS_URL` |
88
94
 
89
- | Service | Default | Env var |
90
- |---------|---------|---------|
91
- | Routing API (markets, execution, keys) | `http://localhost:3002` | `FASTBOOKS_ROUTING_URL` |
92
- | Bots service (deploy, forward-test) | `http://localhost:8003` | `FASTBOOKS_BOTS_URL` |
95
+ > The CLI already targets the hosted FastBooks API — you don't run those services yourself.
96
+ > Just mint a key (`fastbooks apikey create`, free) and set `FASTBOOKS_API_KEY`; platform data
97
+ > is **metered per key**. For trading you never send exchange keys to the server the CLI trades
98
+ > client-side via `direct` with your own keys. Self-hosting the backend? Override the env vars to
99
+ > `http://localhost:3002` / `:8003`.
93
100
 
94
101
  ```bash
95
- fastbooks config show # show resolved URLs
96
- fastbooks config doctor # ping both services
102
+ fastbooks config show # show resolved URLs + stored config
103
+ fastbooks config health # ping the hosted services
97
104
  ```
98
105
 
99
- Auth: FastBooks platform keys (`apikey`) are **fully self-service — no admin
100
- token**. The only token you may need is `FASTBOOKS_API_TOKEN` (a JWT), and only
101
- for storing exchange keys & saved backtests.
102
-
103
106
  ---
104
107
 
105
108
  ## Quickstart — the four core flows
@@ -254,56 +257,3 @@ FASTBOOKS_E2E=1 python3 -m pytest -q # live smoke against running service
254
257
 
255
258
  See [tests/README.md](tests/README.md). The capability suite asserts the CLI
256
259
  hits the correct backend endpoints (method + path + auth) for the four flows.
257
-
258
- ---
259
-
260
- ## Publishing to PyPI
261
-
262
- The package builds from `pyproject.toml` (PEP 621, setuptools backend) — no
263
- Poetry needed. One-time tooling:
264
-
265
- ```bash
266
- pip install --upgrade build twine
267
- ```
268
-
269
- Release steps (run from `cli/`):
270
-
271
- ```bash
272
- # 1. Bump the version in pyproject.toml (e.g. 0.2.0 -> 0.2.1)
273
- # 2. Build sdist + wheel into dist/
274
- python3 -m build
275
-
276
- # 3. Sanity-check the metadata
277
- twine check dist/*
278
-
279
- # 4. Upload to TestPyPI first (recommended), then verify the install
280
- twine upload --repository testpypi dist/*
281
- pipx install --index-url https://test.pypi.org/simple/ fastbooks-cli
282
-
283
- # 5. Upload to real PyPI
284
- twine upload dist/*
285
- ```
286
-
287
- Auth uses an API token (create at https://pypi.org/manage/account/token/). Put it in
288
- `~/.pypirc` or pass it as the password with username `__token__`:
289
-
290
- ```ini
291
- # ~/.pypirc
292
- [pypi]
293
- username = __token__
294
- password = pypi-AgEN...your-token...
295
- [testpypi]
296
- username = __token__
297
- password = pypi-AgEN...your-testpypi-token...
298
- ```
299
-
300
- Notes:
301
- - The project name `fastbooks-cli` must be free on PyPI (check
302
- https://pypi.org/project/fastbooks-cli/); the `fastbooks` command name is unaffected by that.
303
- - `MANIFEST.in` ships `README.md`, `SKILL.md`, `EXCHANGES.md`, `LICENSE`, and `examples/`
304
- in the sdist. Only the `fastbooks_cli` package is included — **no strategy logic**.
305
- - Each upload version is immutable; bump the version for every release.
306
- - For automated releases, use the PyPI **Trusted Publisher** (OIDC) GitHub Action
307
- instead of a long-lived token.
308
- - The proprietary `fastbooks-clistrategies` package is built the same way but
309
- published privately (or installed from a Git URL), never to public PyPI.
File without changes
File without changes
File without changes
File without changes
File without changes