ef22e217c7
CI / lint-test-build (push) Failing after 11s
- Added PG_PASSWORD to .env.example for database connection. - Removed unnecessary imports and streamlined code in various modules. - Enhanced error handling in ConfigSettingRepository and ConfigPairingRepository. - Updated test files to remove unused imports and improve clarity.
84 lines
3.3 KiB
Python
84 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
from collections.abc import AsyncIterator
|
|
from contextlib import asynccontextmanager
|
|
from datetime import UTC, datetime, timedelta
|
|
|
|
import pytest
|
|
|
|
from arbitrade.config.settings import get_settings
|
|
from arbitrade.metrics import MetricsCalculator
|
|
from arbitrade.storage.pg_store import PgStore
|
|
|
|
pytestmark = pytest.mark.integration
|
|
|
|
|
|
@asynccontextmanager
|
|
async def _pg() -> AsyncIterator[PgStore]:
|
|
s = get_settings()
|
|
store = PgStore(s)
|
|
try:
|
|
await store.start()
|
|
await store.migrate()
|
|
yield store
|
|
finally:
|
|
await store.stop()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_metrics_calculator_summarizes_execution_data() -> None:
|
|
async with _pg() as store:
|
|
started = datetime.now(UTC)
|
|
finished = started + timedelta(seconds=30)
|
|
started_two = started + timedelta(minutes=1)
|
|
finished_two = started_two + timedelta(seconds=90)
|
|
|
|
async with store.pool.acquire() as conn:
|
|
await conn.execute(
|
|
"""
|
|
INSERT INTO trades (
|
|
trade_ref, started_at, finished_at, status,
|
|
realized_pnl, estimated_pnl, capital_used, cycle, leg_count
|
|
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9),
|
|
($10, $11, $12, $13, $14, $15, $16, $17, $18)
|
|
""",
|
|
"trade-1", started, finished, "filled", 12.5, 10.0, 100.0, "USD->BTC->ETH->USD", 3,
|
|
"trade-2", started_two, finished_two, "filled", -
|
|
4.5, -2.0, 200.0, "USD->ETH->BTC->USD", 3,
|
|
)
|
|
await conn.execute(
|
|
"""
|
|
INSERT INTO opportunities (detected_at, cycle, gross_pct, net_pct, est_profit, executed)
|
|
VALUES ($1, $2, $3, $4, $5, $6),
|
|
($7, $8, $9, $10, $11, $12),
|
|
($13, $14, $15, $16, $17, $18)
|
|
""",
|
|
started, "USD->BTC->ETH->USD", 4.0, 3.0, 0.03, True,
|
|
started_two, "USD->ETH->BTC->USD", 2.0, 1.0, 0.01, False,
|
|
started_two +
|
|
timedelta(
|
|
seconds=30), "USD->BTC->ETH->USD", 5.0, 4.0, 0.04, True,
|
|
)
|
|
await conn.execute(
|
|
"""
|
|
INSERT INTO orders (
|
|
trade_ref, order_ref, leg_index, pair, side, volume,
|
|
user_ref, status, filled_volume, avg_price, raw_response, recorded_at
|
|
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12),
|
|
($13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24)
|
|
""",
|
|
"trade-1", "order-1", 0, "BTC/USD", "buy", 2.0, 101, "closed", 2.0, 100.0, "{}", started,
|
|
"trade-2", "order-2", 0, "ETH/USD", "sell", 4.0, 202, "closed", 3.0, 200.0, "{}", started_two,
|
|
)
|
|
|
|
metrics = await MetricsCalculator(store).compute()
|
|
|
|
assert metrics.realized_pnl_usd == 8.0
|
|
assert metrics.win_rate == 0.5
|
|
assert metrics.avg_trade_duration_seconds == 60.0
|
|
assert metrics.opportunities_per_minute == 2.0
|
|
assert metrics.fill_rate == 0.875
|
|
assert metrics.latency_p50_seconds == 60.0
|
|
assert metrics.latency_p95_seconds == 87.0
|
|
assert metrics.latency_p99_seconds == pytest.approx(89.4)
|