📊 Logi handlowe — logTrade()
HornX™ zapisuje szczegółowy log każdego trade'u do pliku executor_tradelog.json (per użytkownik, max 500 wpisów). Od sesji 30-03-2026 każdy wpis zawiera pełne dane do analizy i uczenia AI.
Gdzie są logi?
data/users/{userId}/executor_tradelog.json
- Max 500 wpisów na użytkownika (najnowsze na górze)
- Automatyczny backup
.bakprzy każdym zapisie - Dostępne przez dashboard → zakładka Historia
Struktura wpisu
Każdy wpis zawiera pola bazowe (od zawsze) + 16 nowych pól dodanych w FIX-TRADELOG (commit 19f513c):
{
"symbol": "BTCUSDT",
"side": "long",
"entry": 82450.0,
"exit": 83200.0,
"sl": 81900.0,
"tp": 83500.0,
"result": "tp1_hit",
"pnl": 18.40,
"size": 0.024,
"mode": "paper",
"orderId": "4521893712",
"aqs": 87,
"signalScore": 74,
"tradeId": "4521893712",
"strategy": "TrendFollow",
"direction": "LONG",
"timeframe": "15m",
"leverage": 10,
"positionUsdt": 1980.0,
"tp2": 84100.0,
"tp3": 85000.0,
"exitPrice": 83200.0,
"exitTime": "2026-03-30T14:22:11.000Z",
"exitReason": "TP1_HIT",
"feesUsdt": 2.38,
"netPnlUsdt": 16.02,
"pnlPct": 0.81,
"aiDecision": "CONFIRM",
"aiProvider": "groq",
"aiConfidence": 82,
"aiReason": "Strong trend continuation, volume above avg, RSI not overbought",
"timestamp": "2026-03-30T14:22:11.123Z"
}
Opis 16 nowych pól
Identyfikacja i kontekst strategii
| Pole | Typ | Opis |
|---|---|---|
tradeId | string | orderId z giełdy lub wewnętrzny klucz trade'u |
strategy | string | Nazwa strategii ATE (np. TrendFollow, BreakOut, DipHunter) |
direction | string | LONG lub SHORT |
timeframe | string | Timeframe sygnału: 1m, 5m, 15m, 1H, 4H |
Ekspozycja na ryzyko
| Pole | Typ | Opis |
|---|---|---|
leverage | number | Efektywna dźwignia użyta przy wejściu |
positionUsdt | number | Wartość pozycji w USDT (size * entry) |
tp2 | number | Drugi target zysku (jeśli ustawiony) |
tp3 | number | Trzeci target zysku (jeśli ustawiony) |
Dane zamknięcia
| Pole | Typ | Opis |
|---|---|---|
exitPrice | number | Cena zamknięcia pozycji |
exitTime | string | ISO 8601 timestamp zamknięcia |
exitReason | string | Powód zamknięcia (patrz tabela niżej) |
Możliwe wartości exitReason:
| Wartość | Kiedy |
|---|---|
TP1_HIT | Zamknięcie na pierwszym targecie |
SL_HIT | Stop loss trafiony |
EMERGENCY | SL placement failed — pozycja zamknięta awaryjnie |
KILL_SWITCH | Wyłącznik kill-switch aktywowany |
ACCOUNT_RESET | Reset konta papierowego |
CLOSED_ON_EXCHANGE | Pozycja zamknięta na giełdzie podczas przestoju bota |
Wynik finansowy (auto-obliczane)
| Pole | Typ | Wzór | Opis |
|---|---|---|---|
feesUsdt | number | positionUsdt × 0.0006 × 2 | Szacowane opłaty (WEEX taker 0.06%, wejście + wyjście) |
netPnlUsdt | number | pnl - feesUsdt | Wynik netto po opłatach |
pnlPct | number | (pnl / positionUsdt) × 100 | Procent zysku/straty od wartości pozycji |
notatka
Wartości feesUsdt, netPnlUsdt, pnlPct są szacowane. Faktyczne opłaty zależą od poziomu VIP i slippage.
Werdykt AI
| Pole | Typ | Opis |
|---|---|---|
aiDecision | string | CONFIRM, REJECT, lub SKIP (brak AI) |
aiProvider | string | Model który podjął decyzję: groq, deepseek, gemini |
aiConfidence | number | Pewność AI w skali 0–100 |
aiReason | string | Uzasadnienie AI (max 500 znaków) |
Pipeline: Sygnał → logTrade
ATE generuje sygnał (ate-signal-gen.js)
↓
ate-controller.js: AI walidacja → _lastAiVerdict
↓ formatSignal(sig) → execSignal
↓ execSignal.strategy = sig.strategy
↓ execSignal.aiDecision = _lastAiVerdict.decision
↓ execSignal.aiProvider / aiConfidence / aiReason
↓
weex-executor.js: processSignal(execSignal)
↓ handleEntrySignal({ ..., strategy, aiDecision, ... })
↓
openTrades.set(key, {
...,
strategy, direction, timeframe,
leverage, positionUsdt,
aiDecision, aiProvider, aiConfidence, aiReason
})
↓
_handleCloseInternal() → logTrade(entry, {
strategy: trade.strategy,
exitPrice, exitTime, exitReason,
feesUsdt, ← auto-computed
netPnlUsdt, ← auto-computed
pnlPct, ← auto-computed
aiDecision: trade.aiDecision,
...
})
↓
executor_tradelog.json
Jak używać logów do analizy?
Filtrowanie po strategii
const logs = JSON.parse(fs.readFileSync('data/users/1/executor_tradelog.json'));
const trendFollow = logs.filter(t => t.strategy === 'TrendFollow');
Skuteczność AI
const aiTrades = logs.filter(t => t.aiDecision === 'CONFIRM');
const aiWins = aiTrades.filter(t => t.pnl > 0).length;
const aiWinRate = (aiWins / aiTrades.length * 100).toFixed(1);
Najgorszy provider
const byProvider = {};
logs.forEach(t => {
if (!t.aiProvider) return;
byProvider[t.aiProvider] = byProvider[t.aiProvider] || { pnl: 0, count: 0 };
byProvider[t.aiProvider].pnl += t.netPnlUsdt || 0;
byProvider[t.aiProvider].count++;
});
Powiązane
- AI Walidacja sygnałów — jak działa system decyzyjny AI
- Historia tradów — widok logów w dashboardzie
- Changelog — historia zmian