The NetTrader backend communicates with clients via two primary mechanisms: a standard HTTP REST API for CRUD operations and state changes, and a SignalR WebSocket Hub for low-latency, real-time telemetry.
Crucial Note: The entire application uses
camelCasefor JSON serialization. This applies to REST responses, SignalR payloads, and Enum string representations.
All protected endpoints require a Bearer token (Authorization: Bearer <JWT>) retrieved from the authentication flow.
If an endpoint requires Exchange API keys but the user hasn't configured them, the server returns a specific 400 Bad Request error.
Error 400 Example (EXCHANGE_KEYS_MISSING)
{
"error": "EXCHANGE_KEYS_MISSING",
"message": "API keys not found"
}Handles User Registration, Login, and Token issuing.
POST /api/auth/register/request-code: Send an OTP to an email.POST /api/auth/register/confirm: Validate OTP, create user, return JWT.POST /api/auth/login: Standard Email/Password login.POST /api/auth/google: OAuth login via Google ID Token.
Successful Login Response
{
"token": "eyJhbGciOiJIUzI1...",
"expiration": "2024-05-20T14:30:00Z"
}Note: The Refresh Token is securely stored in an HttpOnly cookie (refreshToken).
GET /api/balance: Retrieves real-time margin and wallet balances from the active Exchange. ReturnsEXCHANGE_KEYS_MISSINGif no keys exist.POST /api/settings/keys: Securely stores AES-encrypted Exchange API keys.
GET /api/positions: Returns the user's active trading sessions alongside live PnL calculations retrieved from the database.DELETE /api/positions/{symbol}: Issues a manual market close for the specific pair.POST /api/bot/panic: Emergency stop; immediately closes all active positions.POST /api/bot/cycle: Triggers an immediate, out-of-schedule AI scan and trading execution loop.
The SignalR hub is hosted at /hubs/trading.
Clients must connect using the access_token query parameter or bearer header.
The SignalRBroadcastService orchestrates these pushes. It relies heavily on local caching (database or memory) to prevent spamming Exchange REST APIs.
Broadcast every 10 seconds. Contains an array of market snapshots for pre-validated pairs (as defined in SymbolConfig).
It wraps the array in a symbols property to accommodate future metadata extensions.
Event: MarketScan
Payload:
{
"symbols": [
{
"symbol": "BTCUSDT",
"exchange": "Binance",
"price": 64500.50,
"change24h": 2.5,
"high24h": 65000.00,
"low24h": 62000.00,
"volume24h": 45000.5,
"mlSignal": "None",
"mlBuyProbability": 0.35,
"mlShortProbability": 0.45,
"rsi": 55.2
},
{
"symbol": "ETHUSDT",
"exchange": "Bybit",
"price": 3400.20,
"change24h": -1.2,
"high24h": 3500.00,
"low24h": 3350.00,
"volume24h": 120000.1,
"mlSignal": "Short",
"mlBuyProbability": 0.20,
"mlShortProbability": 0.85,
"rsi": 32.1
}
],
"scanType": "Snapshot"
}Broadcast every 1 second. Lightweight ticker updates to drive UI animations and sparklines.
Event: PriceUpdate
Payload:
{
"symbol": "BTCUSDT",
"price": 64510.00,
"change24h": 2.52,
"high24h": 65000.00,
"low24h": 62000.00
}Broadcast every 2 seconds. Details the user's currently active trade sessions and local PnL state.
Event: PositionUpdate
Payload:
[
{
"symbol": "ETHUSDT",
"exchange": "Bybit",
"status": "active",
"entryPrice": 3405.00,
"currentPrice": 3400.20,
"pnl": -4.80,
"roe": -1.4,
"leverage": 10,
"quantity": 1.5,
"direction": "short"
}
]Streams diagnostic logs and critical alerts directly to the user dashboard.
Event: EmergencyAlert
Payload:
{
"type": "MarginWarning",
"message": "Available margin dropped below $50. Cannot open new positions."
}