Changes include: - Updated architecture documentation - Enhanced module definitions (OQI-001 to OQI-008) - ML integration documentation updates - Trading strategies documentation - Orchestration and inventory updates - Docker configuration updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 KiB
| id | title | type | status | priority | epic | story_points | created_date | updated_date |
|---|---|---|---|---|---|---|---|---|
| US-TRD-014 | Resetear Balance de Paper Trading | User Story | Done | Media | OQI-003 | 2 | 2025-12-05 | 2026-01-04 |
US-TRD-014: Resetear Balance de Paper Trading
Metadata
| Campo | Valor |
|---|---|
| ID | US-TRD-014 |
| Épica | OQI-003 - Trading y Charts |
| Módulo | trading |
| Prioridad | P2 |
| Story Points | 1 |
| Sprint | Sprint 6 |
| Estado | Pendiente |
| Asignado a | Por asignar |
Historia de Usuario
Como trader practicante, quiero resetear mi balance de paper trading a $10,000, para empezar de nuevo con una cuenta limpia y practicar con nuevas estrategias.
Descripción Detallada
El usuario debe poder resetear completamente su cuenta de paper trading, eliminando todas las posiciones abiertas, órdenes pendientes, y restaurando el balance a $10,000 USD. Esta funcionalidad es útil cuando el usuario quiere empezar de cero o después de hacer pruebas extensivas.
Mockups/Wireframes
┌─────────────────────────────────────────────────────────────────┐
│ ACCOUNT SETTINGS - Paper Trading │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Current Balance: $8,456.78 │
│ Equity: $8,567.23 │
│ Open Positions: 3 │
│ Pending Orders: 2 │
│ Total Trades: 67 │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ ⚠ RESET ACCOUNT │ │
│ ├────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ Reset your paper trading account to start fresh: │ │
│ │ │ │
│ │ This action will: │ │
│ │ ✓ Close all open positions (3) │ │
│ │ ✓ Cancel all pending orders (2) │ │
│ │ ✓ Reset balance to $10,000.00 │ │
│ │ ✓ Clear trade history (67 trades) │ │
│ │ ✓ Reset statistics │ │
│ │ │ │
│ │ ⚠ This action CANNOT be undone! │ │
│ │ │ │
│ │ [Reset Account] │ │
│ └────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────┐
│ CONFIRM ACCOUNT RESET │
├─────────────────────────────────────┤
│ Are you sure you want to reset │
│ your paper trading account? │
│ │
│ You will lose: │
│ • All open positions (3) │
│ • All pending orders (2) │
│ • Trade history (67 trades) │
│ • All statistics │
│ │
│ Your account will be reset to: │
│ • Balance: $10,000.00 │
│ • No positions │
│ • No history │
│ │
│ Type "RESET" to confirm: │
│ ┌─────────────────────────────────┐ │
│ │ │ │
│ └─────────────────────────────────┘ │
│ │
│ [Cancel] [Confirm Reset] │
└─────────────────────────────────────┘
Criterios de Aceptación
Escenario 1: Reset exitoso con confirmación
DADO que el usuario tiene:
- Balance: $8,456.78
- 3 posiciones abiertas
- 2 órdenes pendientes
- 67 trades en historial
CUANDO hace click en "Reset Account"
Y confirma escribiendo "RESET"
Y hace click en "Confirm Reset"
ENTONCES se cierran todas las posiciones
Y se cancelan todas las órdenes
Y el balance se resetea a $10,000.00
Y el historial se limpia
Y las estadísticas se resetean
Y se muestra mensaje "Account reset successfully"
Escenario 2: Cancelar reset
DADO que el usuario abre el diálogo de reset
CUANDO hace click en "Cancel"
ENTONCES no se realiza ningún cambio
Y el diálogo se cierra
Y el balance permanece igual
Escenario 3: Validación de confirmación
DADO que el usuario está en el diálogo de reset
CUANDO no escribe "RESET" correctamente
ENTONCES el botón "Confirm Reset" está deshabilitado
Y no puede proceder
CUANDO escribe "RESET" exactamente
ENTONCES el botón se habilita
Y puede confirmar
Escenario 4: Reset sin posiciones abiertas
DADO que el usuario no tiene posiciones ni órdenes
Y solo quiere resetear el balance
CUANDO ejecuta el reset
ENTONCES el balance se restaura a $10,000
Y el historial se limpia
Y se muestra mensaje confirmando el reset
Escenario 5: Cooldown period
DADO que el usuario acaba de resetear su cuenta
CUANDO intenta resetear nuevamente inmediatamente
ENTONCES se muestra mensaje "You can reset again in 23:59:45"
Y el botón "Reset Account" está deshabilitado por 24 horas
Criterios Adicionales
- Cooldown de 24 horas entre resets
- Backup automático antes de reset (último estado)
- Email de confirmación después del reset
- Opción de "Undo" durante 5 minutos después del reset
- Contador de resets en perfil de usuario
Tareas Técnicas
Database:
- DB-TRD-023: Crear tabla trading.account_resets
- Campos: id, user_id, previous_balance, reset_at
- DB-TRD-024: Añadir soft delete a trades (backup)
Backend:
- BE-TRD-078: Crear endpoint POST /trading/paper/reset
- BE-TRD-079: Implementar AccountResetService.reset()
- BE-TRD-080: Cerrar todas las posiciones
- BE-TRD-081: Cancelar todas las órdenes pendientes
- BE-TRD-082: Limpiar/archivar historial
- BE-TRD-083: Resetear balance a $10,000
- BE-TRD-084: Implementar cooldown de 24 horas
- BE-TRD-085: Crear backup antes del reset
Frontend:
- FE-TRD-076: Crear componente AccountSettings.tsx
- FE-TRD-077: Crear componente ResetAccountDialog.tsx
- FE-TRD-078: Crear componente ConfirmResetDialog.tsx
- FE-TRD-079: Implementar hook useResetAccount
- FE-TRD-080: Implementar countdown para cooldown
Tests:
- TEST-TRD-037: Test unitario reset completo
- TEST-TRD-038: Test integración reset con posiciones
- TEST-TRD-039: Test E2E flujo completo reset
Dependencias
Depende de:
- US-TRD-006: Crear orden - Estado: Pendiente
- US-TRD-008: Cerrar posición - Estado: Pendiente
Bloquea:
- Ninguna
Notas Técnicas
Endpoints involucrados:
| Método | Endpoint | Descripción |
|---|---|---|
| POST | /trading/paper/reset | Resetear cuenta |
| GET | /trading/paper/reset/status | Verificar si puede resetear |
Entidades/Tablas:
CREATE TABLE trading.account_resets (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES auth.users(id),
previous_balance DECIMAL(20, 8) NOT NULL,
previous_equity DECIMAL(20, 8) NOT NULL,
open_positions INTEGER DEFAULT 0,
pending_orders INTEGER DEFAULT 0,
total_trades INTEGER DEFAULT 0,
reset_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_account_resets_user
ON trading.account_resets(user_id, reset_at DESC);
-- Para cooldown
ALTER TABLE auth.users
ADD COLUMN last_reset_at TIMESTAMP;
Componentes UI:
AccountSettings: Página de configuraciónResetAccountDialog: Diálogo principalConfirmResetDialog: Modal de confirmaciónCooldownTimer: Timer de cooldown
Request Body:
{
confirmation: "RESET"
}
Response (Reset):
{
success: true,
previousState: {
balance: 8456.78,
equity: 8567.23,
openPositions: 3,
pendingOrders: 2,
totalTrades: 67
},
newState: {
balance: 10000.00,
equity: 10000.00,
openPositions: 0,
pendingOrders: 0,
totalTrades: 0
},
resetAt: "2025-12-05T10:00:00Z",
nextResetAvailableAt: "2025-12-06T10:00:00Z"
}
Response (Status):
{
canReset: false,
lastResetAt: "2025-12-05T10:00:00Z",
nextResetAvailableAt: "2025-12-06T10:00:00Z",
cooldownRemaining: 82800 // segundos
}
Reset Process:
async function resetAccount(userId: string) {
// 1. Verificar cooldown
const lastReset = await getLastResetTime(userId);
if (lastReset && Date.now() - lastReset < 24 * 60 * 60 * 1000) {
throw new Error('Cooldown active');
}
// 2. Crear backup del estado actual
const currentState = await getCurrentAccountState(userId);
await createBackup(userId, currentState);
// 3. Cerrar todas las posiciones
const positions = await getOpenPositions(userId);
for (const position of positions) {
await closePosition(position.id, 'account_reset');
}
// 4. Cancelar todas las órdenes
const orders = await getPendingOrders(userId);
for (const order of orders) {
await cancelOrder(order.id);
}
// 5. Archivar historial (soft delete)
await archiveTradeHistory(userId);
// 6. Resetear balance
await updateBalance(userId, 10000.00);
// 7. Resetear estadísticas
await resetStatistics(userId);
// 8. Registrar reset
await createResetRecord(userId, currentState);
// 9. Actualizar timestamp de último reset
await updateLastResetTime(userId, new Date());
// 10. Enviar email de confirmación
await sendResetConfirmationEmail(userId);
return {
success: true,
previousState: currentState,
newState: {
balance: 10000.00,
equity: 10000.00,
openPositions: 0,
pendingOrders: 0
}
};
}
Cooldown Calculation:
const COOLDOWN_MS = 24 * 60 * 60 * 1000; // 24 horas
function getCooldownStatus(lastResetAt: Date) {
const now = Date.now();
const lastReset = lastResetAt.getTime();
const nextAvailable = lastReset + COOLDOWN_MS;
const remaining = Math.max(0, nextAvailable - now);
return {
canReset: remaining === 0,
lastResetAt,
nextResetAvailableAt: new Date(nextAvailable),
cooldownRemaining: Math.floor(remaining / 1000)
};
}
Definition of Ready (DoR)
- Historia claramente escrita
- Criterios de aceptación definidos
- Story points estimados
- Dependencias identificadas
- Sin bloqueadores
- Diseño/mockup disponible
- API spec disponible
Definition of Done (DoD)
- Código implementado según criterios
- Tests unitarios escritos y pasando
- Tests de integración pasando
- Code review aprobado
- Documentación actualizada
- QA aprobado
- Desplegado en ambiente de pruebas
Historial de Cambios
| Fecha | Cambio | Autor |
|---|---|---|
| 2025-12-05 | Creación | Requirements-Analyst |
Creada por: Requirements-Analyst Fecha: 2025-12-05 Última actualización: 2025-12-05