botlog-analyzer-pro / script.js
kvazarbit's picture
страница которая детално проанализирует поведение торгового бота по лог файлу в том же корене... {"component": "strategy", "symbol": "BTCUSDT", "bar_time": "2025-10-23T14:30:00+00:00", "blocking_reason": "NO_SIGNAL", "score": "0.354", "threshold": "0.500", "delta_score": "-0.146", "edge_net": "-0.0010", "min_edge": "0.0007", "confluence": "3/5", "reasons": "price_up,inertia_up,normal_vol", "vol_ratio": "1.18", "effective_min_vol_ratio": "0.45", "effective_max_vol_ratio": "3.50", "hurst": "0.973", "adx": "17.6", "trend_dir": -1, "market_regime": "RANGING", "h1_trend": "UP", "lagrangian_osc": "-0.895", "strong_uptrend": false, "unhealthy": false, "streak": "0/2", "will_buy": false, "volume_confirm_ok": true, "not_local_breakout": true, "is_momentum": false, "is_reversal": false, "momentum_data": null, "reversal_data": null, "event": "entry_evaluation", "logger": "strategy", "level": "info", "timestamp": "2025-10-27T12:58:58.402047Z"}
a48b488 verified
Raw History Blame Contribute Delete
6.48 kB
// Shared JavaScript across all pages
document.addEventListener('DOMContentLoaded', function() {
// Initialize the log file upload functionality
const logFileInput = document.getElementById('logFile');
if (logFileInput) {
logFileInput.addEventListener('change', handleFileUpload);
}
// Sample data for demonstration
updateSampleData();
});
function handleFileUpload(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
try {
const logData = JSON.parse(e.target.result);
processLogData(logData);
} catch (error) {
console.error('Error parsing log file:', error);
alert('Error parsing log file. Please check the file format.');
}
};
reader.readAsText(file);
}
function processLogData(logData) {
if (!Array.isArray(logData)) {
logData = logData.split('\n').filter(line => line.trim()).map(line => {
try {
return JSON.parse(line);
} catch {
return { message: line };
}
});
}
console.log('Processed log data:', logData);
// Here you would call functions to update the UI with the log data
updateLogTable(logData);
updateStats(logData);
updateTradePerformance(logData);
}
function updateLogTable(logData) {
const tableBody = document.getElementById('logTableBody');
if (!tableBody) return;
// Clear existing rows
tableBody.innerHTML = '';
// Add new rows
logData.slice(0, 50).forEach(entry => {
const row = document.createElement('tr');
row.className = 'log-entry';
if (entry.event === 'paper_buy') row.classList.add('trade-buy');
if (entry.event === 'paper_sell') row.classList.add('trade-sell');
if (entry.reason === 'TAKE_PROFIT') row.classList.add('trade-profit');
if (entry.reason === 'STOP_LOSS') row.classList.add('trade-loss');
const timeCell = document.createElement('td');
timeCell.className = 'px-6 py-4 whitespace-nowrap text-sm text-gray-500';
timeCell.textContent = entry.timestamp ? new Date(entry.timestamp).toLocaleTimeString() : '-';
const eventCell = document.createElement('td');
eventCell.className = 'px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900';
eventCell.textContent = entry.event || '-';
const symbolCell = document.createElement('td');
symbolCell.className = 'px-6 py-4 whitespace-nowrap text-sm text-gray-500';
symbolCell.textContent = entry.symbol || '-';
const detailsCell = document.createElement('td');
detailsCell.className = 'px-6 py-4 text-sm text-gray-500';
if (entry.event === 'entry_evaluation') {
detailsCell.textContent = `Score: ${entry.score || '-'}, Confluence: ${entry.confluence || '-'}`;
} else if (entry.event === 'position_closed') {
detailsCell.textContent = `PNL: ${entry.pnl || '-'} (${entry.pnl_pct || '-'}) - ${entry.reason || ''}`;
} else {
detailsCell.textContent = JSON.stringify(entry, null, 2);
}
row.appendChild(timeCell);
row.appendChild(eventCell);
row.appendChild(symbolCell);
row.appendChild(detailsCell);
tableBody.appendChild(row);
});
feather.replace();
}
function updateStats(logData) {
// Update statistics based on log data
const entryEvaluations = logData.filter(entry => entry.event === 'entry_evaluation');
if (entryEvaluations.length > 0) {
const avgScore = entryEvaluations.reduce((sum, entry) => sum + parseFloat(entry.score || 0), 0) / entryEvaluations.length;
document.getElementById('scoreThreshold').textContent = entryEvaluations[0].threshold || '0.500';
document.getElementById('avgDeltaScore').textContent = avgScore.toFixed(3);
const marketRegime = entryEvaluations[0].market_regime || 'UNKNOWN';
document.getElementById('marketRegime').textContent = marketRegime;
const h1Trend = entryEvaluations[0].h1_trend || 'UNKNOWN';
document.getElementById('h1Trend').textContent = h1Trend;
}
}
function updateTradePerformance(logData) {
// Update trade performance metrics
const trades = logData.filter(entry => entry.event === 'position_closed');
if (trades.length > 0) {
const tradeStats = document.querySelector('trade-stats');
if (tradeStats) {
tradeStats.setAttribute('total-trades', trades.length);
const profitableTrades = trades.filter(trade => trade.pnl_pct && !trade.pnl_pct.startsWith('-')).length;
tradeStats.setAttribute('win-rate', Math.round((profitableTrades / trades.length) * 100));
const totalPnl = trades.reduce((sum, trade) => {
const pnl = parseFloat(trade.pnl_pct?.replace('%', '') || '0');
return sum + pnl;
}, 0);
tradeStats.setAttribute('avg-pnl', (totalPnl / trades.length).toFixed(2));
}
}
}
function updateSampleData() {
// For demo purposes, load sample data
const sampleLogs = [
{
"component": "strategy",
"symbol": "BTCUSDT",
"bar_time": "2025-10-23T14:30:00+00:00",
"blocking_reason": "NO_SIGNAL",
"score": "0.354",
"threshold": "0.500",
"delta_score": "-0.146",
"event": "entry_evaluation",
"timestamp": "2025-10-27T12:58:58.402047Z"
},
{
"component": "paper",
"symbol": "BTCUSDT",
"quantity": 0.000904,
"price": 110758.52727600001,
"event": "paper_buy",
"timestamp": "2025-10-27T13:03:05.864671Z"
},
{
"symbol": "BTCUSDT",
"loss": "-0.49%",
"reason": "ATR_SL",
"event": "stop_loss_triggered",
"timestamp": "2025-10-27T13:06:00.383211Z"
},
{
"symbol": "BTCUSDT",
"profit": "1.00%",
"reason": "ATR_TP",
"event": "take_profit_triggered",
"timestamp": "2025-10-27T13:21:12.387101Z"
}
];
processLogData(sampleLogs);
}