Add explicit trade sizing
This commit is contained in:
@@ -5,12 +5,19 @@ from typing import Any
|
||||
|
||||
from llm_trade_bot.bybit_gateway import BybitGateway
|
||||
from llm_trade_bot.config import BybitConfig, ScannerConfig
|
||||
from llm_trade_bot.models import Category, OpenTradeRequest, OrderType, Side, ValidatedOrder
|
||||
|
||||
|
||||
class FakeBybitHTTP:
|
||||
def __init__(self, wallet: dict[str, Any] | None = None) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
wallet: dict[str, Any] | None = None,
|
||||
open_orders: dict[str, list[dict[str, Any]]] | None = None,
|
||||
) -> None:
|
||||
self.wallet = wallet
|
||||
self.open_orders = open_orders or {}
|
||||
self.open_order_requests: list[dict[str, Any]] = []
|
||||
self.placed_orders: list[dict[str, Any]] = []
|
||||
|
||||
def get_wallet_balance(self, **parameters: Any) -> dict[str, Any]:
|
||||
assert parameters == {"accountType": "UNIFIED"}
|
||||
@@ -21,7 +28,14 @@ class FakeBybitHTTP:
|
||||
|
||||
def get_open_orders(self, **parameters: Any) -> dict[str, Any]:
|
||||
self.open_order_requests.append(parameters)
|
||||
return {"retCode": 0, "result": {"list": []}}
|
||||
return {
|
||||
"retCode": 0,
|
||||
"result": {"list": self.open_orders.get(str(parameters["category"]), [])},
|
||||
}
|
||||
|
||||
def place_order(self, **parameters: Any) -> dict[str, Any]:
|
||||
self.placed_orders.append(parameters)
|
||||
return {"retCode": 0, "result": {"orderId": "order-1"}}
|
||||
|
||||
|
||||
async def test_open_orders_scopes_linear_requests_by_settle_coin() -> None:
|
||||
@@ -44,7 +58,7 @@ async def test_account_snapshot_uses_quote_coin_balance_when_account_available_i
|
||||
"list": [
|
||||
{
|
||||
"totalEquity": "100000",
|
||||
"totalAvailableBalance": "",
|
||||
"totalAvailableBalance": "99999",
|
||||
"totalMarginBalance": "100000",
|
||||
"coin": [
|
||||
{
|
||||
@@ -70,3 +84,80 @@ async def test_account_snapshot_uses_quote_coin_balance_when_account_available_i
|
||||
|
||||
assert spot.available_balance == Decimal("49000")
|
||||
assert linear.available_balance == Decimal("50000")
|
||||
|
||||
|
||||
async def test_account_snapshot_uses_open_spot_orders_when_reported_locked_is_stale() -> None:
|
||||
wallet = {
|
||||
"retCode": 0,
|
||||
"result": {
|
||||
"list": [
|
||||
{
|
||||
"totalEquity": "100005",
|
||||
"totalAvailableBalance": "50005",
|
||||
"coin": [
|
||||
{
|
||||
"coin": "USDT",
|
||||
"walletBalance": "100005",
|
||||
"availableToWithdraw": "",
|
||||
"totalPositionIM": "0",
|
||||
"totalOrderIM": "50000",
|
||||
"locked": "0",
|
||||
"bonus": "0",
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
open_orders = {
|
||||
"spot": [
|
||||
{
|
||||
"category": "spot",
|
||||
"symbol": "BTCUSDT",
|
||||
"side": "Buy",
|
||||
"orderStatus": "New",
|
||||
"leavesQty": "0.586166",
|
||||
"leavesValue": "49999.96",
|
||||
"price": "85300",
|
||||
}
|
||||
]
|
||||
}
|
||||
gateway = BybitGateway(BybitConfig("key", "secret", "USDT"), ScannerConfig(quote_coin="USDT"))
|
||||
gateway._http = FakeBybitHTTP(wallet, open_orders) # type: ignore[assignment]
|
||||
|
||||
snapshot = await gateway.account_snapshot("linear")
|
||||
|
||||
assert snapshot.available_balance == Decimal("5.04")
|
||||
|
||||
|
||||
async def test_spot_market_order_sends_base_coin_quantity() -> None:
|
||||
gateway = BybitGateway(BybitConfig("key", "secret"), ScannerConfig())
|
||||
http = FakeBybitHTTP()
|
||||
gateway._http = http # type: ignore[assignment]
|
||||
request = OpenTradeRequest(
|
||||
category=Category.SPOT,
|
||||
symbol="BTCUSDT",
|
||||
side=Side.BUY,
|
||||
order_type=OrderType.MARKET,
|
||||
reference_price=Decimal("100000"),
|
||||
limit_price=None,
|
||||
stop_loss=Decimal("90000"),
|
||||
take_profit=Decimal("110000"),
|
||||
trailing_distance=None,
|
||||
leverage=Decimal(1),
|
||||
rationale="test",
|
||||
)
|
||||
order = ValidatedOrder(
|
||||
entry_price=Decimal("100000"),
|
||||
quantity=Decimal("0.5"),
|
||||
notional=Decimal("50000"),
|
||||
stop_loss=Decimal("90000"),
|
||||
take_profit=Decimal("110000"),
|
||||
trailing_distance=None,
|
||||
leverage=Decimal(1),
|
||||
)
|
||||
|
||||
await gateway.open_trade(request, order, "ltb-test")
|
||||
|
||||
assert http.placed_orders[0]["qty"] == "0.5"
|
||||
assert http.placed_orders[0]["marketUnit"] == "baseCoin"
|
||||
|
||||
Reference in New Issue
Block a user