fere-cli 0.4.0__tar.gz → 0.4.0.dev37__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 (25) hide show
  1. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/PKG-INFO +2 -2
  2. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/pyproject.toml +2 -2
  3. fere_cli-0.4.0.dev37/src/fere_cli/commands/spot_hl.py +229 -0
  4. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/main.py +4 -0
  5. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/.gitignore +0 -0
  6. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/README.md +0 -0
  7. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/install.sh +0 -0
  8. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/__init__.py +0 -0
  9. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/async_util.py +0 -0
  10. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/banner.py +0 -0
  11. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/__init__.py +0 -0
  12. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/auth.py +0 -0
  13. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/chat.py +0 -0
  14. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/earn.py +0 -0
  15. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/hooks.py +0 -0
  16. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/limit_order.py +0 -0
  17. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/perp.py +0 -0
  18. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/portfolio.py +0 -0
  19. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/swap.py +0 -0
  20. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/commands/utility.py +0 -0
  21. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/config.py +0 -0
  22. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/output.py +0 -0
  23. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/src/fere_cli/update.py +0 -0
  24. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/tests/test_install_sh.py +0 -0
  25. {fere_cli-0.4.0 → fere_cli-0.4.0.dev37}/tests/test_update.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fere-cli
3
- Version: 0.4.0
3
+ Version: 0.4.0.dev37
4
4
  Summary: Terminal CLI for FereAI crypto trading and research
5
5
  Author-email: Fere AI <info@fere.ai>
6
6
  License-Expression: MIT
7
7
  Requires-Python: >=3.10
8
8
  Requires-Dist: click>=8.1
9
- Requires-Dist: fere-sdk>=0.5.0
9
+ Requires-Dist: fere-sdk>=0.4.0.dev37
10
10
  Requires-Dist: httpx>=0.27
11
11
  Requires-Dist: rich>=13.0
12
12
  Provides-Extra: dev
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "fere-cli"
3
- version = "0.4.0"
3
+ version = "0.4.0.dev37"
4
4
  description = "Terminal CLI for FereAI crypto trading and research"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
7
  license = "MIT"
8
8
  authors = [{ name = "Fere AI", email = "info@fere.ai" }]
9
9
  dependencies = [
10
- "fere-sdk>=0.5.0",
10
+ "fere-sdk>=0.4.0.dev37",
11
11
  "httpx>=0.27",
12
12
  "click>=8.1",
13
13
  "rich>=13.0",
@@ -0,0 +1,229 @@
1
+ """Spot commands: fere spot (markets, orders, buy, sell, tp-sl, cancel).
2
+
3
+ Venue-neutral HyperCore spot trading. Assets are base symbol only (always
4
+ USDC-quoted); ``size`` is the base-token amount.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import click
10
+ from rich.console import Console
11
+
12
+ from ..async_util import async_command, get_client, is_tty
13
+ from ..output import print_error, print_success
14
+
15
+ console = Console()
16
+
17
+
18
+ @click.group()
19
+ def spot_hl():
20
+ """Trade HyperCore spot assets (buy, sell, tp-sl)."""
21
+ pass
22
+
23
+
24
+ @spot_hl.command()
25
+ @click.option("--search", default=None, help="Filter the asset universe.")
26
+ @click.pass_context
27
+ @async_command
28
+ async def markets(ctx, search):
29
+ """List the tradable spot market universe."""
30
+ try:
31
+ client = await get_client(ctx)
32
+ data = await client.get_spot_hl_markets(search_text=search)
33
+ await client.close()
34
+ print_success(data)
35
+ except click.ClickException:
36
+ raise
37
+ except Exception as e:
38
+ print_error(str(e))
39
+ raise SystemExit(1)
40
+
41
+
42
+ @spot_hl.command()
43
+ @click.pass_context
44
+ @async_command
45
+ async def orders(ctx):
46
+ """List open spot orders (incl. TP/SL triggers)."""
47
+ try:
48
+ client = await get_client(ctx)
49
+ data = await client.get_spot_hl_orders()
50
+ await client.close()
51
+ print_success(data)
52
+ except click.ClickException:
53
+ raise
54
+ except Exception as e:
55
+ print_error(str(e))
56
+ raise SystemExit(1)
57
+
58
+
59
+ @spot_hl.command()
60
+ @click.option("--asset", required=True, help="Base asset symbol, e.g. HYPE.")
61
+ @click.option("--size", required=True, type=float, help="Base-token amount.")
62
+ @click.option(
63
+ "--order-type",
64
+ default="market",
65
+ type=click.Choice(["market", "limit"]),
66
+ )
67
+ @click.option("--limit-price", default=None, type=float)
68
+ @click.option("--slippage-pct", default=0.5, type=float)
69
+ @click.option("--tp-price", default=None, type=float, help="Take-profit.")
70
+ @click.option("--sl-price", default=None, type=float, help="Stop-loss.")
71
+ @click.option(
72
+ "--timeout", default=120, type=int, help="Wait timeout (seconds)."
73
+ )
74
+ @click.option("-y", "--yes", is_flag=True, help="Skip confirmation.")
75
+ @click.pass_context
76
+ @async_command
77
+ async def buy(
78
+ ctx,
79
+ asset,
80
+ size,
81
+ order_type,
82
+ limit_price,
83
+ slippage_pct,
84
+ tp_price,
85
+ sl_price,
86
+ timeout,
87
+ yes,
88
+ ):
89
+ """Buy a spot asset with USDC."""
90
+ if not yes and is_tty():
91
+ click.echo(f"Buy {size} {asset} ({order_type})")
92
+ if not click.confirm("Proceed?"):
93
+ raise SystemExit(0)
94
+ try:
95
+ client = await get_client(ctx)
96
+ with console.status("Buying..."):
97
+ result = await client.spot_hl_buy(
98
+ asset=asset,
99
+ size=size,
100
+ order_type=order_type,
101
+ limit_price=limit_price,
102
+ slippage_pct=slippage_pct,
103
+ tp_price=tp_price,
104
+ sl_price=sl_price,
105
+ timeout=timeout,
106
+ )
107
+ await client.close()
108
+ print_success(result)
109
+ except click.ClickException:
110
+ raise
111
+ except Exception as e:
112
+ print_error(str(e))
113
+ raise SystemExit(1)
114
+
115
+
116
+ @spot_hl.command()
117
+ @click.option("--asset", required=True, help="Base asset symbol to sell.")
118
+ @click.option(
119
+ "--size",
120
+ default=None,
121
+ type=float,
122
+ help="Base-token amount; omit to sell the full balance.",
123
+ )
124
+ @click.option(
125
+ "--order-type",
126
+ default="market",
127
+ type=click.Choice(["market", "limit"]),
128
+ )
129
+ @click.option("--limit-price", default=None, type=float)
130
+ @click.option("--slippage-pct", default=0.5, type=float)
131
+ @click.option(
132
+ "--timeout", default=120, type=int, help="Wait timeout (seconds)."
133
+ )
134
+ @click.option("-y", "--yes", is_flag=True, help="Skip confirmation.")
135
+ @click.pass_context
136
+ @async_command
137
+ async def sell(
138
+ ctx, asset, size, order_type, limit_price, slippage_pct, timeout, yes
139
+ ):
140
+ """Sell a held spot asset back to USDC."""
141
+ if not yes and is_tty():
142
+ amt = f"{size}" if size is not None else "full balance"
143
+ click.echo(f"Sell {amt} {asset} ({order_type})")
144
+ if not click.confirm("Proceed?"):
145
+ raise SystemExit(0)
146
+ try:
147
+ client = await get_client(ctx)
148
+ with console.status("Selling..."):
149
+ result = await client.spot_hl_sell(
150
+ asset=asset,
151
+ size=size,
152
+ order_type=order_type,
153
+ limit_price=limit_price,
154
+ slippage_pct=slippage_pct,
155
+ timeout=timeout,
156
+ )
157
+ await client.close()
158
+ print_success(result)
159
+ except click.ClickException:
160
+ raise
161
+ except Exception as e:
162
+ print_error(str(e))
163
+ raise SystemExit(1)
164
+
165
+
166
+ @spot_hl.command(name="tp-sl")
167
+ @click.option("--asset", required=True, help="Held asset symbol to protect.")
168
+ @click.option("--tp-price", default=None, type=float, help="Take-profit.")
169
+ @click.option("--sl-price", default=None, type=float, help="Stop-loss.")
170
+ @click.option(
171
+ "--size",
172
+ default=None,
173
+ type=float,
174
+ help="Base amount; omit for the full held balance.",
175
+ )
176
+ @click.option(
177
+ "--timeout", default=120, type=int, help="Wait timeout (seconds)."
178
+ )
179
+ @click.pass_context
180
+ @async_command
181
+ async def tp_sl(ctx, asset, tp_price, sl_price, size, timeout):
182
+ """Attach reduce-side TP/SL sell triggers to a held spot asset."""
183
+ if tp_price is None and sl_price is None:
184
+ print_error("Provide at least one of --tp-price / --sl-price")
185
+ raise SystemExit(1)
186
+ try:
187
+ client = await get_client(ctx)
188
+ with console.status("Setting TP/SL..."):
189
+ result = await client.spot_hl_set_tp_sl(
190
+ asset=asset,
191
+ tp_price=tp_price,
192
+ sl_price=sl_price,
193
+ size=size,
194
+ timeout=timeout,
195
+ )
196
+ await client.close()
197
+ print_success(result)
198
+ except click.ClickException:
199
+ raise
200
+ except Exception as e:
201
+ print_error(str(e))
202
+ raise SystemExit(1)
203
+
204
+
205
+ @spot_hl.command()
206
+ @click.option("--asset", required=True, help="Asset symbol of the order.")
207
+ @click.option(
208
+ "--order-id", required=True, type=int, help="Venue order id (oid)."
209
+ )
210
+ @click.option(
211
+ "--timeout", default=120, type=int, help="Wait timeout (seconds)."
212
+ )
213
+ @click.pass_context
214
+ @async_command
215
+ async def cancel(ctx, asset, order_id, timeout):
216
+ """Cancel an open spot order by its venue order id."""
217
+ try:
218
+ client = await get_client(ctx)
219
+ with console.status("Cancelling order..."):
220
+ result = await client.spot_hl_cancel_order(
221
+ asset=asset, order_id=order_id, timeout=timeout
222
+ )
223
+ await client.close()
224
+ print_success(result)
225
+ except click.ClickException:
226
+ raise
227
+ except Exception as e:
228
+ print_error(str(e))
229
+ raise SystemExit(1)
@@ -12,6 +12,7 @@ from .commands.hooks import hooks
12
12
  from .commands.limit_order import limit_order
13
13
  from .commands.perp import perp
14
14
  from .commands.portfolio import holdings, notifications, wallets
15
+ from .commands.spot_hl import spot_hl
15
16
  from .commands.swap import swap
16
17
  from .commands.utility import chains, config, status
17
18
  from .update import maybe_check_for_updates
@@ -94,6 +95,9 @@ cli.add_command(earn)
94
95
  # Perp (venue-neutral perpetual futures)
95
96
  cli.add_command(perp)
96
97
 
98
+ # Spot (venue-neutral HyperCore spot)
99
+ cli.add_command(spot_hl, name="spot-hl")
100
+
97
101
  # Utility
98
102
  cli.add_command(chains)
99
103
  cli.add_command(status)
File without changes
File without changes
File without changes