tradetracker / index.html
Fendertrader's picture
undefined - Initial Deployment
1ac1537 verified
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TradeTracker - Registro de Operaciones</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.chart-container {
height: 300px;
position: relative;
}
.trade-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.animated-underline {
position: relative;
display: inline-block;
}
.animated-underline::after {
content: '';
position: absolute;
width: 0;
height: 2px;
bottom: -2px;
left: 0;
background-color: #3b82f6;
transition: width 0.3s ease;
}
.animated-underline:hover::after {
width: 100%;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: #cbd5e0;
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: #a0aec0;
}
</style>
</head>
<body class="bg-gray-50 font-sans">
<div class="flex h-screen overflow-hidden">
<!-- Sidebar -->
<div class="hidden md:flex md:flex-shrink-0">
<div class="flex flex-col w-64 bg-indigo-700 text-white">
<div class="flex items-center justify-center h-16 px-4 border-b border-indigo-600">
<div class="flex items-center">
<i class="fas fa-chart-line text-2xl mr-2 text-indigo-200"></i>
<span class="text-xl font-bold">TradeTracker</span>
</div>
</div>
<div class="flex flex-col flex-grow px-4 py-4 overflow-y-auto">
<nav class="flex-1 space-y-2">
<a href="#" class="flex items-center px-4 py-3 text-sm font-medium rounded-md bg-indigo-800 text-white">
<i class="fas fa-home mr-3"></i>
Dashboard
</a>
<a href="#" class="flex items-center px-4 py-3 text-sm font-medium rounded-md text-indigo-200 hover:bg-indigo-600 hover:text-white">
<i class="fas fa-plus-circle mr-3"></i>
Nueva Operación
</a>
<a href="#" class="flex items-center px-4 py-3 text-sm font-medium rounded-md text-indigo-200 hover:bg-indigo-600 hover:text-white">
<i class="fas fa-list mr-3"></i>
Historial
</a>
<a href="#" class="flex items-center px-4 py-3 text-sm font-medium rounded-md text-indigo-200 hover:bg-indigo-600 hover:text-white">
<i class="fas fa-chart-pie mr-3"></i>
Estadísticas
</a>
<a href="#" class="flex items-center px-4 py-3 text-sm font-medium rounded-md text-indigo-200 hover:bg-indigo-600 hover:text-white">
<i class="fas fa-cog mr-3"></i>
Configuración
</a>
</nav>
<div class="mt-auto pb-4">
<div class="px-4 py-3 bg-indigo-800 rounded-md">
<div class="flex items-center">
<img class="h-8 w-8 rounded-full" src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="User profile">
<div class="ml-3">
<p class="text-sm font-medium">Trader</p>
<p class="text-xs font-medium text-indigo-200">Premium</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Main content -->
<div class="flex flex-col flex-1 overflow-hidden">
<!-- Mobile header -->
<div class="md:hidden flex items-center justify-between px-4 py-3 bg-indigo-700 text-white">
<div class="flex items-center">
<i class="fas fa-chart-line text-xl mr-2"></i>
<span class="text-lg font-bold">TradeTracker</span>
</div>
<button id="mobile-menu-button" class="text-white focus:outline-none">
<i class="fas fa-bars text-xl"></i>
</button>
</div>
<!-- Mobile sidebar (hidden by default) -->
<div id="mobile-menu" class="hidden md:hidden bg-indigo-800 text-white">
<nav class="px-2 py-4 space-y-1">
<a href="#" class="block px-3 py-2 rounded-md text-base font-medium bg-indigo-900 text-white">
<i class="fas fa-home mr-2"></i>Dashboard
</a>
<a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-indigo-200 hover:bg-indigo-700 hover:text-white">
<i class="fas fa-plus-circle mr-2"></i>Nueva Operación
</a>
<a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-indigo-200 hover:bg-indigo-700 hover:text-white">
<i class="fas fa-list mr-2"></i>Historial
</a>
<a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-indigo-200 hover:bg-indigo-700 hover:text-white">
<i class="fas fa-chart-pie mr-2"></i>Estadísticas
</a>
<a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-indigo-200 hover:bg-indigo-700 hover:text-white">
<i class="fas fa-cog mr-2"></i>Configuración
</a>
</nav>
</div>
<!-- Main content area -->
<div class="flex-1 overflow-auto p-4 md:p-6">
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-800">Registro de Operaciones</h1>
<p class="text-gray-600">Seguimiento y análisis de tus trades</p>
</div>
<!-- Stats cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
<div class="bg-white rounded-lg shadow p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-gray-500">Ganancia Total</p>
<p class="text-2xl font-bold text-green-500">$4,250.50</p>
</div>
<div class="p-3 rounded-full bg-green-100 text-green-600">
<i class="fas fa-arrow-up"></i>
</div>
</div>
<div class="mt-2">
<span class="text-sm text-green-600">+12.5% este mes</span>
</div>
</div>
<div class="bg-white rounded-lg shadow p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-gray-500">Operaciones</p>
<p class="text-2xl font-bold text-indigo-600">42</p>
</div>
<div class="p-3 rounded-full bg-indigo-100 text-indigo-600">
<i class="fas fa-exchange-alt"></i>
</div>
</div>
<div class="mt-2">
<span class="text-sm text-gray-600">15 este mes</span>
</div>
</div>
<div class="bg-white rounded-lg shadow p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-gray-500">Tasa de éxito</p>
<p class="text-2xl font-bold text-blue-500">68.3%</p>
</div>
<div class="p-3 rounded-full bg-blue-100 text-blue-600">
<i class="fas fa-percentage"></i>
</div>
</div>
<div class="mt-2">
<span class="text-sm text-blue-600">+5.2% este mes</span>
</div>
</div>
<div class="bg-white rounded-lg shadow p-4">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-gray-500">Riesgo/Recompensa</p>
<p class="text-2xl font-bold text-purple-500">1:2.4</p>
</div>
<div class="p-3 rounded-full bg-purple-100 text-purple-600">
<i class="fas fa-balance-scale"></i>
</div>
</div>
<div class="mt-2">
<span class="text-sm text-gray-600">Promedio</span>
</div>
</div>
</div>
<!-- Main content grid -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Trade form and recent trades -->
<div class="lg:col-span-2 space-y-6">
<!-- Add trade form -->
<div class="bg-white rounded-lg shadow overflow-hidden">
<div class="px-6 py-4 border-b border-gray-200">
<h2 class="text-lg font-medium text-gray-900">Nueva Operación</h2>
</div>
<div class="p-6">
<form id="tradeForm">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label for="symbol" class="block text-sm font-medium text-gray-700 mb-1">Activo</label>
<input type="text" id="symbol" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" placeholder="Ej: AAPL, BTC/USD">
</div>
<div>
<label for="market" class="block text-sm font-medium text-gray-700 mb-1">Mercado</label>
<select id="market" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
<option value="stocks">Acciones</option>
<option value="forex">Forex</option>
<option value="crypto">Criptomonedas</option>
<option value="futures">Futuros</option>
<option value="options">Opciones</option>
</select>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label for="direction" class="block text-sm font-medium text-gray-700 mb-1">Dirección</label>
<select id="direction" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
<option value="long">Compra (Long)</option>
<option value="short">Venta (Short)</option>
</select>
</div>
<div>
<label for="size" class="block text-sm font-medium text-gray-700 mb-1">Tamaño</label>
<input type="number" id="size" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" placeholder="Ej: 100">
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label for="entryPrice" class="block text-sm font-medium text-gray-700 mb-1">Precio de entrada</label>
<input type="number" step="0.01" id="entryPrice" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" placeholder="Ej: 145.32">
</div>
<div>
<label for="exitPrice" class="block text-sm font-medium text-gray-700 mb-1">Precio de salida</label>
<input type="number" step="0.01" id="exitPrice" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" placeholder="Ej: 148.75">
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<label for="stopLoss" class="block text-sm font-medium text-gray-700 mb-1">Stop Loss</label>
<input type="number" step="0.01" id="stopLoss" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" placeholder="Ej: 143.50">
</div>
<div>
<label for="takeProfit" class="block text-sm font-medium text-gray-700 mb-1">Take Profit</label>
<input type="number" step="0.01" id="takeProfit" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" placeholder="Ej: 150.00">
</div>
</div>
<div class="mb-4">
<label for="notes" class="block text-sm font-medium text-gray-700 mb-1">Notas</label>
<textarea id="notes" rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" placeholder="Estrategia, emociones, etc."></textarea>
</div>
<div class="flex justify-end">
<button type="button" id="saveTrade" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<i class="fas fa-save mr-2"></i>Guardar Operación
</button>
</div>
</form>
</div>
</div>
<!-- Recent trades -->
<div class="bg-white rounded-lg shadow overflow-hidden">
<div class="px-6 py-4 border-b border-gray-200 flex justify-between items-center">
<h2 class="text-lg font-medium text-gray-900">Operaciones Recientes</h2>
<div class="flex space-x-2">
<button class="px-3 py-1 text-sm bg-gray-100 rounded-md hover:bg-gray-200">
<i class="fas fa-filter mr-1"></i>Filtrar
</button>
<button class="px-3 py-1 text-sm bg-gray-100 rounded-md hover:bg-gray-200">
<i class="fas fa-download mr-1"></i>Exportar
</button>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Fecha</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Activo</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Dirección</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Resultado</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Acciones</th>
</tr>
</thead>
<tbody id="tradesTableBody" class="bg-white divide-y divide-gray-200">
<!-- Trades will be added here by JavaScript -->
</tbody>
</table>
</div>
</div>
</div>
<!-- Right sidebar with charts and performance -->
<div class="space-y-6">
<!-- Performance chart -->
<div class="bg-white rounded-lg shadow p-4">
<div class="flex justify-between items-center mb-4">
<h2 class="text-lg font-medium text-gray-900">Rendimiento</h2>
<select class="text-sm border border-gray-300 rounded-md px-2 py-1 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
<option>7 días</option>
<option>30 días</option>
<option selected>90 días</option>
<option>1 año</option>
</select>
</div>
<div class="chart-container">
<canvas id="performanceChart"></canvas>
</div>
</div>
<!-- Win rate and stats -->
<div class="bg-white rounded-lg shadow p-4">
<h2 class="text-lg font-medium text-gray-900 mb-4">Estadísticas Clave</h2>
<div class="space-y-4">
<div>
<div class="flex justify-between mb-1">
<span class="text-sm font-medium text-gray-700">Tasa de éxito</span>
<span class="text-sm font-medium text-gray-700">68.3%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div class="bg-green-500 h-2.5 rounded-full" style="width: 68.3%"></div>
</div>
</div>
<div>
<div class="flex justify-between mb-1">
<span class="text-sm font-medium text-gray-700">Operaciones ganadoras</span>
<span class="text-sm font-medium text-gray-700">28/42</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div class="bg-green-500 h-2.5 rounded-full" style="width: 66.6%"></div>
</div>
</div>
<div>
<div class="flex justify-between mb-1">
<span class="text-sm font-medium text-gray-700">Operaciones perdedoras</span>
<span class="text-sm font-medium text-gray-700">14/42</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div class="bg-red-500 h-2.5 rounded-full" style="width: 33.3%"></div>
</div>
</div>
</div>
</div>
<!-- Best performing assets -->
<div class="bg-white rounded-lg shadow overflow-hidden">
<div class="px-4 py-3 border-b border-gray-200">
<h2 class="text-lg font-medium text-gray-900">Activos más rentables</h2>
</div>
<div class="divide-y divide-gray-200">
<div class="px-4 py-3 flex justify-between items-center">
<div class="flex items-center">
<div class="p-2 rounded-full bg-blue-100 text-blue-600 mr-3">
<i class="fas fa-chart-line"></i>
</div>
<div>
<p class="font-medium">AAPL</p>
<p class="text-sm text-gray-500">Apple Inc.</p>
</div>
</div>
<span class="text-green-500 font-medium">+$1,245.50</span>
</div>
<div class="px-4 py-3 flex justify-between items-center">
<div class="flex items-center">
<div class="p-2 rounded-full bg-purple-100 text-purple-600 mr-3">
<i class="fas fa-coins"></i>
</div>
<div>
<p class="font-medium">BTC/USD</p>
<p class="text-sm text-gray-500">Bitcoin</p>
</div>
</div>
<span class="text-green-500 font-medium">+$876.30</span>
</div>
<div class="px-4 py-3 flex justify-between items-center">
<div class="flex items-center">
<div class="p-2 rounded-full bg-indigo-100 text-indigo-600 mr-3">
<i class="fas fa-chart-line"></i>
</div>
<div>
<p class="font-medium">TSLA</p>
<p class="text-sm text-gray-500">Tesla Inc.</p>
</div>
</div>
<span class="text-green-500 font-medium">+$543.20</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Trade details modal -->
<div id="tradeModal" class="fixed inset-0 z-50 hidden overflow-y-auto">
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div class="absolute inset-0 bg-gray-500 opacity-75"></div>
</div>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
<div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-2xl sm:w-full">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modalTitle">
Detalles de la Operación
</h3>
<button id="closeModal" class="text-gray-400 hover:text-gray-500">
<i class="fas fa-times"></i>
</button>
</div>
<div class="mt-2">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<p class="text-sm text-gray-500">Activo</p>
<p id="modalSymbol" class="font-medium"></p>
</div>
<div>
<p class="text-sm text-gray-500">Mercado</p>
<p id="modalMarket" class="font-medium"></p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<p class="text-sm text-gray-500">Dirección</p>
<p id="modalDirection" class="font-medium"></p>
</div>
<div>
<p class="text-sm text-gray-500">Tamaño</p>
<p id="modalSize" class="font-medium"></p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<p class="text-sm text-gray-500">Precio entrada</p>
<p id="modalEntry" class="font-medium"></p>
</div>
<div>
<p class="text-sm text-gray-500">Precio salida</p>
<p id="modalExit" class="font-medium"></p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<div>
<p class="text-sm text-gray-500">Stop Loss</p>
<p id="modalSL" class="font-medium"></p>
</div>
<div>
<p class="text-sm text-gray-500">Take Profit</p>
<p id="modalTP" class="font-medium"></p>
</div>
</div>
<div class="mb-4">
<p class="text-sm text-gray-500">Resultado</p>
<p id="modalResult" class="text-xl font-bold"></p>
</div>
<div>
<p class="text-sm text-gray-500">Notas</p>
<p id="modalNotes" class="font-medium"></p>
</div>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button type="button" id="deleteTrade" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
Eliminar
</button>
<button type="button" id="editTrade" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
Editar
</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
// Mobile menu toggle
document.getElementById('mobile-menu-button').addEventListener('click', function() {
const menu = document.getElementById('mobile-menu');
menu.classList.toggle('hidden');
});
// Sample trades data
let trades = [
{
id: 1,
date: '2023-06-15',
symbol: 'AAPL',
market: 'stocks',
direction: 'long',
size: 50,
entryPrice: 145.32,
exitPrice: 148.75,
stopLoss: 143.50,
takeProfit: 150.00,
notes: 'Breakout de resistencia en marco 1H. Objetivo alcanzado.',
result: 171.50
},
{
id: 2,
date: '2023-06-14',
symbol: 'BTC/USD',
market: 'crypto',
direction: 'short',
size: 0.1,
entryPrice: 26450,
exitPrice: 26210,
stopLoss: 26600,
takeProfit: 26000,
notes: 'Rechazo en resistencia clave. Tomé ganancias antes del objetivo.',
result: 24.00
},
{
id: 3,
date: '2023-06-12',
symbol: 'EUR/USD',
market: 'forex',
direction: 'long',
size: 10000,
entryPrice: 1.0825,
exitPrice: 1.0780,
stopLoss: 1.0800,
takeProfit: 1.0900,
notes: 'Falso breakout. Stop loss movido muy cerca.',
result: -45.00
},
{
id: 4,
date: '2023-06-10',
symbol: 'TSLA',
market: 'stocks',
direction: 'long',
size: 20,
entryPrice: 240.50,
exitPrice: 248.75,
stopLoss: 235.00,
takeProfit: 255.00,
notes: 'Rebote en soporte importante con volumen.',
result: 165.00
}
];
// Render trades table
function renderTradesTable() {
const tableBody = document.getElementById('tradesTableBody');
tableBody.innerHTML = '';
trades.forEach(trade => {
const row = document.createElement('tr');
const resultClass = trade.result >= 0 ? 'text-green-500' : 'text-red-500';
const resultSymbol = trade.result >= 0 ? '+' : '';
const directionClass = trade.direction === 'long' ? 'text-green-500' : 'text-red-500';
const directionText = trade.direction === 'long' ? 'Compra' : 'Venta';
row.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${trade.date}</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-gray-200 flex items-center justify-center">
${trade.market === 'stocks' ? '<i class="fas fa-chart-line text-gray-600"></i>' :
trade.market === 'forex' ? '<i class="fas fa-dollar-sign text-gray-600"></i>' :
trade.market === 'crypto' ? '<i class="fab fa-bitcoin text-gray-600"></i>' :
'<i class="fas fa-exchange-alt text-gray-600"></i>'}
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900">${trade.symbol}</div>
<div class="text-sm text-gray-500">${getMarketName(trade.market)}</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${directionClass}">
${directionText}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm ${resultClass}">
${resultSymbol}$${Math.abs(trade.result).toFixed(2)}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button class="text-indigo-600 hover:text-indigo-900 mr-3 view-trade" data-id="${trade.id}">Ver</button>
<button class="text-gray-600 hover:text-gray-900 edit-trade" data-id="${trade.id}">Editar</button>
</td>
`;
tableBody.appendChild(row);
});
// Add event listeners to view buttons
document.querySelectorAll('.view-trade').forEach(button => {
button.addEventListener('click', function() {
const tradeId = parseInt(this.getAttribute('data-id'));
viewTrade(tradeId);
});
});
// Add event listeners to edit buttons
document.querySelectorAll('.edit-trade').forEach(button => {
button.addEventListener('click', function() {
const tradeId = parseInt(this.getAttribute('data-id'));
editTrade(tradeId);
});
});
}
// Get market name
function getMarketName(market) {
const markets = {
'stocks': 'Acciones',
'forex': 'Forex',
'crypto': 'Cripto',
'futures': 'Futuros',
'options': 'Opciones'
};
return markets[market] || market;
}
// View trade details
function viewTrade(tradeId) {
const trade = trades.find(t => t.id === tradeId);
if (!trade) return;
document.getElementById('modalSymbol').textContent = trade.symbol;
document.getElementById('modalMarket').textContent = getMarketName(trade.market);
document.getElementById('modalDirection').textContent = trade.direction === 'long' ? 'Compra (Long)' : 'Venta (Short)';
document.getElementById('modalSize').textContent = trade.size;
document.getElementById('modalEntry').textContent = `$${trade.entryPrice.toFixed(2)}`;
document.getElementById('modalExit').textContent = trade.exitPrice ? `$${trade.exitPrice.toFixed(2)}` : 'N/A';
document.getElementById('modalSL').textContent = trade.stopLoss ? `$${trade.stopLoss.toFixed(2)}` : 'N/A';
document.getElementById('modalTP').textContent = trade.takeProfit ? `$${trade.takeProfit.toFixed(2)}` : 'N/A';
document.getElementById('modalNotes').textContent = trade.notes || 'No hay notas';
const resultElement = document.getElementById('modalResult');
if (trade.result >= 0) {
resultElement.textContent = `+$${trade.result.toFixed(2)}`;
resultElement.className = 'text-xl font-bold text-green-500';
} else {
resultElement.textContent = `-$${Math.abs(trade.result).toFixed(2)}`;
resultElement.className = 'text-xl font-bold text-red-500';
}
// Set data attributes for edit/delete
document.getElementById('deleteTrade').setAttribute('data-id', trade.id);
document.getElementById('editTrade').setAttribute('data-id', trade.id);
// Show modal
document.getElementById('tradeModal').classList.remove('hidden');
}
// Edit trade
function editTrade(tradeId) {
const trade = trades.find(t => t.id === tradeId);
if (!trade) return;
// Fill the form with trade data
document.getElementById('symbol').value = trade.symbol;
document.getElementById('market').value = trade.market;
document.getElementById('direction').value = trade.direction;
document.getElementById('size').value = trade.size;
document.getElementById('entryPrice').value = trade.entryPrice;
document.getElementById('exitPrice').value = trade.exitPrice || '';
document.getElementById('stopLoss').value = trade.stopLoss || '';
document.getElementById('takeProfit').value = trade.takeProfit || '';
document.getElementById('notes').value = trade.notes || '';
// Change button text
document.getElementById('saveTrade').innerHTML = '<i class="fas fa-save mr-2"></i>Actualizar Operación';
document.getElementById('saveTrade').setAttribute('data-id', trade.id);
// Scroll to form
document.getElementById('symbol').scrollIntoView({ behavior: 'smooth' });
// Close modal if open
document.getElementById('tradeModal').classList.add('hidden');
}
// Delete trade
document.getElementById('deleteTrade').addEventListener('click', function() {
const tradeId = parseInt(this.getAttribute('data-id'));
if (confirm('¿Estás seguro de que quieres eliminar esta operación?')) {
trades = trades.filter(t => t.id !== tradeId);
renderTradesTable();
document.getElementById('tradeModal').classList.add('hidden');
updateCharts();
}
});
// Close modal
document.getElementById('closeModal').addEventListener('click', function() {
document.getElementById('tradeModal').classList.add('hidden');
});
// Save/update trade
document.getElementById('saveTrade').addEventListener('click', function() {
const tradeId = this.getAttribute('data-id');
const isUpdate = !!tradeId;
const symbol = document.getElementById('symbol').value.trim();
const market = document.getElementById('market').value;
const direction = document.getElementById('direction').value;
const size = parseFloat(document.getElementById('size').value);
const entryPrice = parseFloat(document.getElementById('entryPrice').value);
const exitPrice = document.getElementById('exitPrice').value ? parseFloat(document.getElementById('exitPrice').value) : null;
const stopLoss = document.getElementById('stopLoss').value ? parseFloat(document.getElementById('stopLoss').value) : null;
const takeProfit = document.getElementById('takeProfit').value ? parseFloat(document.getElementById('takeProfit').value) : null;
const notes = document.getElementById('notes').value.trim();
// Calculate result
let result = 0;
if (exitPrice) {
if (direction === 'long') {
result = (exitPrice - entryPrice) * size;
} else {
result = (entryPrice - exitPrice) * size;
}
}
if (isUpdate) {
// Update existing trade
const index = trades.findIndex(t => t.id === parseInt(tradeId));
if (index !== -1) {
trades[index] = {
...trades[index],
symbol,
market,
direction,
size,
entryPrice,
exitPrice,
stopLoss,
takeProfit,
notes,
result
};
}
} else {
// Add new trade
const newTrade = {
id: trades.length > 0 ? Math.max(...trades.map(t => t.id)) + 1 : 1,
date: new Date().toISOString().split('T')[0],
symbol,
market,
direction,
size,
entryPrice,
exitPrice,
stopLoss,
takeProfit,
notes,
result
};
trades.push(newTrade);
}
// Reset form
document.getElementById('tradeForm').reset();
document.getElementById('saveTrade').innerHTML = '<i class="fas fa-save mr-2"></i>Guardar Operación';
document.getElementById('saveTrade').removeAttribute('data-id');
// Update UI
renderTradesTable();
updateCharts();
});
// Initialize performance chart
let performanceChart;
function initPerformanceChart() {
const ctx = document.getElementById('performanceChart').getContext('2d');
// Prepare data
const labels = [];
const data = [0]; // Start at 0
let cumulative = 0;
// Sort trades by date
const sortedTrades = [...trades].sort((a, b) => new Date(a.date) - new Date(b.date));
sortedTrades.forEach(trade => {
labels.push(trade.date);
cumulative += trade.result;
data.push(cumulative);
});
performanceChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Inicio', ...labels],
datasets: [{
label: 'Balance acumulado',
data: data,
backgroundColor: 'rgba(99, 102, 241, 0.1)',
borderColor: 'rgba(99, 102, 241, 1)',
borderWidth: 2,
tension: 0.1,
fill: true,
pointBackgroundColor: 'rgba(99, 102, 241, 1)',
pointBorderColor: '#fff',
pointHoverRadius: 5,
pointHoverBackgroundColor: 'rgba(99, 102, 241, 1)',
pointHoverBorderColor: '#fff',
pointHitRadius: 10,
pointBorderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
label: function(context) {
return `Balance: $${context.raw.toFixed(2)}`;
}
}
}
},
scales: {
x: {
grid: {
display: false
}
},
y: {
beginAtZero: false,
ticks: {
callback: function(value) {
return '$' + value;
}
}
}
}
}
});
}
// Update charts when data changes
function updateCharts() {
if (performanceChart) {
// Prepare data
const labels = [];
const data = [0]; // Start at 0
let cumulative = 0;
// Sort trades by date
const sortedTrades = [...trades].sort((a, b) => new Date(a.date) - new Date(b.date));
sortedTrades.forEach(trade => {
labels.push(trade.date);
cumulative += trade.result;
data.push(cumulative);
});
// Update chart data
performanceChart.data.labels = ['Inicio', ...labels];
performanceChart.data.datasets[0].data = data;
performanceChart.update();
}
}
// Initialize the app
document.addEventListener('DOMContentLoaded', function() {
renderTradesTable();
initPerformanceChart();
// Close modal when clicking outside
document.getElementById('tradeModal').addEventListener('click', function(e) {
if (e.target === this) {
this.classList.add('hidden');
}
});
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Fendertrader/tradetracker" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>