Files
llm-trade-bot/tests/test_agent_tools.py
2026-09-22 11:43:32 +02:00

102 lines
3.2 KiB
Python

from datetime import time
from decimal import Decimal
from pathlib import Path
from zoneinfo import ZoneInfo
import pytest
from llm_trade_bot.agent import AgentTools
from llm_trade_bot.config import (
AppConfig,
BraveConfig,
BybitConfig,
ZaiConfig,
PromptsConfig,
ScannerConfig,
ScheduleConfig,
StorageConfig,
TelegramConfig,
)
from llm_trade_bot.database import Database
from llm_trade_bot.models import AccountSnapshot, InstrumentRules
class FakeBybit:
def __init__(self):
self.orders = []
async def account_state(self):
return {"wallet": [{"coin": []}], "positions": [], "open_orders": []}
async def market_context(self, category, symbol):
return {"ticker": {"lastPrice": "100"}}
async def account_snapshot(self):
return AccountSnapshot(Decimal(10000), Decimal(10000), Decimal(0), 0)
async def instrument_rules(self, category, symbol):
return InstrumentRules(Decimal("0.1"), Decimal("0.001"), Decimal("0.001"), Decimal(5), Decimal(100))
async def set_leverage(self, symbol, leverage):
return {"retCode": 0}
async def place_order(self, **parameters):
self.orders.append(parameters)
return {"retCode": 0, "result": {"orderId": f"order-{len(self.orders)}"}}
def make_config(database_path: Path) -> AppConfig:
return AppConfig(
ZaiConfig("key"),
BybitConfig("key", "secret"),
TelegramConfig(1, "hash", "token", frozenset({1})),
BraveConfig("key"),
PromptsConfig(database_path.parent / "prompts.md"),
ScheduleConfig(ZoneInfo("Europe/Warsaw"), (time(9), time(21))),
ScannerConfig(),
StorageConfig(database_path),
)
async def test_open_trade_uses_all_available_buying_power_and_allows_repeated_entries(tmp_path):
database = Database(tmp_path / "state.db")
await database.open()
bybit = FakeBybit()
tools = AgentTools(make_config(database.path), database, bybit) # type: ignore[arg-type]
run_id = await database.start_run("test")
context = {"run_id": run_id}
try:
first = await tools.open_trade(
"linear", "BTCUSDT", "Buy", "Market", 90, "test", take_profit=120, leverage=3, context=context
)
second = await tools.open_trade(
"linear", "BTCUSDT", "Buy", "Market", 90, "test", take_profit=120, leverage=3, context=context
)
assert first["quantity"] == "300"
assert second["quantity"] == "300"
assert len(bybit.orders) == 2
assert bybit.orders[0]["stopLoss"] == "90"
finally:
await database.close()
async def test_pause_blocks_entry_from_running_session(tmp_path):
database = Database(tmp_path / "state.db")
await database.open()
tools = AgentTools(make_config(database.path), database, FakeBybit()) # type: ignore[arg-type]
await database.set_state("paused", "true")
try:
with pytest.raises(ValueError, match="paused"):
await tools.open_trade(
"linear",
"BTCUSDT",
"Buy",
"Market",
90,
"test",
take_profit=120,
context={"run_id": 1},
)
finally:
await database.close()