from __future__ import annotations from crypto_spot_bot.bybit import BybitClient, _looks_like_leveraged_token, _looks_like_stablecoin def test_leveraged_token_filter() -> None: assert _looks_like_leveraged_token("BTC3L") assert _looks_like_leveraged_token("ETHDOWN") assert not _looks_like_leveraged_token("BTC") def test_stablecoin_filter() -> None: assert _looks_like_stablecoin("USDC") assert _looks_like_stablecoin("FDUSD") assert not _looks_like_stablecoin("BTC") def test_spot_instrument_uses_min_order_amt_and_base_precision(make_settings, tmp_path) -> None: client = BybitClient(make_settings(tmp_path)) client.public_get = lambda *_args, **_kwargs: { "list": [ { "symbol": "BTCUSDT", "baseCoin": "BTC", "quoteCoin": "USDT", "status": "Trading", "priceFilter": {"tickSize": "0.01"}, "lotSizeFilter": { "basePrecision": "0.000001", "minOrderQty": "0.000001", "minOrderAmt": "5", }, } ] } instrument = client.instruments()["BTCUSDT"] assert instrument.qty_step == 0.000001 assert instrument.min_notional_value == 5.0 def test_live_spot_order_explicitly_disables_leverage(make_settings, tmp_path) -> None: client = BybitClient(make_settings(tmp_path)) captured = {} def fake_private_post(path, payload): captured["path"] = path captured["payload"] = payload return {"orderId": "test"} client.private_post = fake_private_post client.place_spot_market_order("BTCUSDT", "Buy", 10, "quoteCoin", "order-1") assert captured["path"] == "/v5/order/create" assert captured["payload"]["category"] == "spot" assert captured["payload"]["isLeverage"] == 0 assert captured["payload"]["orderFilter"] == "Order"