from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Enum, Boolean, Date, JSON, Text from sqlalchemy.orm import relationship from sqlalchemy.sql import func import enum from app.db.database import Base class TradeAction(str, enum.Enum): BUY = "BUY" SELL = "SELL" class Simulation(Base): __tablename__ = "simulations" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, nullable=True) # For future multi-user support symbol = Column(String, default="XAU/USD") initial_capital = Column(Float, default=100000.0) current_capital = Column(Float, default=100000.0) total_pnl = Column(Float, default=0.0) total_pnl_percent = Column(Float, default=0.0) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) trades = relationship("Trade", back_populates="simulation", cascade="all, delete-orphan") positions = relationship("Position", back_populates="simulation", cascade="all, delete-orphan") class Trade(Base): __tablename__ = "trades" id = Column(Integer, primary_key=True, index=True) simulation_id = Column(Integer, ForeignKey("simulations.id")) action = Column(Enum(TradeAction)) quantity = Column(Float) price = Column(Float) total = Column(Float) pnl = Column(Float, nullable=True) timestamp = Column(DateTime(timezone=True), server_default=func.now()) simulation = relationship("Simulation", back_populates="trades") class Position(Base): __tablename__ = "positions" id = Column(Integer, primary_key=True, index=True) simulation_id = Column(Integer, ForeignKey("simulations.id")) symbol = Column(String, default="XAU/USD") quantity = Column(Float) avg_price = Column(Float) current_price = Column(Float) unrealized_pnl = Column(Float) unrealized_pnl_percent = Column(Float) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) simulation = relationship("Simulation", back_populates="positions") class AIAnalysisLog(Base): __tablename__ = "ai_analysis_logs" id = Column(Integer, primary_key=True, index=True) simulation_id = Column(Integer, nullable=True) recommendation = Column(String) confidence = Column(Float) reasoning = Column(String) risk_level = Column(String) support_levels = Column(String) # JSON string resistance_levels = Column(String) # JSON string created_at = Column(DateTime(timezone=True), server_default=func.now()) # Phase 1: Daily Helper Enhancements class UserProfile(Base): """User profile and preferences for daily helper features""" __tablename__ = "user_profiles" id = Column(Integer, primary_key=True, index=True) email = Column(String, unique=True, index=True, nullable=True) username = Column(String, unique=True, index=True, nullable=True) timezone = Column(String, default="UTC") preferred_trading_start = Column(String, default="09:00") # HH:MM format preferred_trading_end = Column(String, default="17:00") # HH:MM format risk_tolerance = Column(String, default="moderate") # conservative, moderate, aggressive trading_style = Column(String, default="day_trader") # scalper, day_trader, swing_trader daily_target = Column(Float, nullable=True) # Daily profit target max_loss = Column(Float, nullable=True) # Maximum loss tolerance notifications_enabled = Column(Boolean, default=True) email_reports = Column(Boolean, default=True) sms_enabled = Column(Boolean, default=False) push_notifications = Column(Boolean, default=True) phone_number = Column(String, nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) class DailyRoutine(Base): """Scheduled daily trading routines""" __tablename__ = "daily_routines" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, nullable=True) routine_type = Column(String) # morning, active_trading, evening scheduled_time = Column(String) # HH:MM format tasks = Column(JSON, default=[]) # List of task names enabled = Column(Boolean, default=True) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) class RoutineExecution(Base): """Track routine execution history""" __tablename__ = "routine_executions" id = Column(Integer, primary_key=True, index=True) routine_id = Column(Integer, ForeignKey("daily_routines.id")) executed_at = Column(DateTime(timezone=True), server_default=func.now()) completion_status = Column(String) # completed, failed, partial tasks_completed = Column(JSON, default=[]) # List of completed task names execution_notes = Column(Text, nullable=True) class Notification(Base): """System notifications for user""" __tablename__ = "notifications" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, nullable=True) notification_type = Column(String) # price_alert, routine, report, news, reminder title = Column(String) message = Column(Text) priority = Column(String, default="normal") # low, normal, high, critical delivery_method = Column(String, default="push") # push, email, sms data = Column(JSON, nullable=True) # Additional metadata read = Column(Boolean, default=False) created_at = Column(DateTime(timezone=True), server_default=func.now()) read_at = Column(DateTime(timezone=True), nullable=True) class DailyChecklist(Base): """Daily checklist items and completion status""" __tablename__ = "daily_checklists" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, nullable=True) checklist_date = Column(Date, default=func.current_date()) checklist_type = Column(String) # morning, active_trading, evening, all items = Column(JSON, default=[]) # List of {id, title, completed, completed_at} completion_percentage = Column(Float, default=0.0) notes = Column(Text, nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) class HabitTracker(Base): """Track user habits and streaks""" __tablename__ = "habit_trackers" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, nullable=True) habit_name = Column(String) # journaling, planning, review, trading frequency = Column(String) # daily, weekly completion_dates = Column(JSON, default=[]) # List of ISO date strings current_streak = Column(Integer, default=0) longest_streak = Column(Integer, default=0) total_completions = Column(Integer, default=0) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) # Phase 3: Advanced Analytics class PerformanceSnapshot(Base): """Daily performance snapshot for historical tracking""" __tablename__ = "performance_snapshots" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, nullable=True) snapshot_date = Column(Date, default=func.current_date()) daily_pnl = Column(Float, default=0.0) daily_pnl_percent = Column(Float, default=0.0) total_trades = Column(Integer, default=0) winning_trades = Column(Integer, default=0) losing_trades = Column(Integer, default=0) win_rate = Column(Float, default=0.0) best_trade = Column(Float, nullable=True) worst_trade = Column(Float, nullable=True) avg_win = Column(Float, nullable=True) avg_loss = Column(Float, nullable=True) sharpe_ratio = Column(Float, nullable=True) profit_factor = Column(Float, nullable=True) max_drawdown = Column(Float, nullable=True) cumulative_pnl = Column(Float, default=0.0) portfolio_value = Column(Float, nullable=True) equity_curve = Column(JSON, default=[]) # Time series streak_type = Column(String, nullable=True) # win_streak, loss_streak streak_count = Column(Integer, default=0) created_at = Column(DateTime(timezone=True), server_default=func.now()) class TradePattern(Base): """Identified profitable trade patterns""" __tablename__ = "trade_patterns" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, nullable=True) pattern_name = Column(String) # e.g., "Morning breakout", "Reversal near support" description = Column(Text, nullable=True) win_rate = Column(Float) # Percentage avg_win = Column(Float) avg_loss = Column(Float) sample_count = Column(Integer) # Number of matching trades best_timeframe = Column(String, nullable=True) # 1m, 5m, 15m, 1h, 1d best_time_of_day = Column(String, nullable=True) # e.g., "09:30-10:30" confidence_score = Column(Float) # 0-100 indicators_used = Column(JSON, default=[]) # List of indicators market_conditions = Column(String, nullable=True) # bullish, bearish, neutral total_profit = Column(Float, default=0.0) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) class LessonLearned(Base): """Track lessons and insights from trading""" __tablename__ = "lessons_learned" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, nullable=True) date_learned = Column(DateTime(timezone=True), server_default=func.now()) category = Column(String) # entry, exit, risk, psychology, market lesson_text = Column(Text) related_trades = Column(JSON, default=[]) # Trade IDs impact = Column(String) # positive, negative, neutral tags = Column(JSON, default=[]) # Searchable tags importance = Column(String) # critical, important, helpful status = Column(String, default="active") # active, archived created_at = Column(DateTime(timezone=True), server_default=func.now()) class MonthlyReview(Base): """Monthly trading performance review""" __tablename__ = "monthly_reviews" id = Column(Integer, primary_key=True, index=True) user_id = Column(String, nullable=True) year = Column(Integer) month = Column(Integer) total_trades = Column(Integer, default=0) total_pnl = Column(Float, default=0.0) total_pnl_percent = Column(Float, default=0.0) best_day = Column(Date, nullable=True) worst_day = Column(Date, nullable=True) best_trade = Column(Float, nullable=True) worst_trade = Column(Float, nullable=True) win_rate = Column(Float, default=0.0) avg_daily_pnl = Column(Float, nullable=True) sharpe_ratio = Column(Float, nullable=True) max_drawdown = Column(Float, nullable=True) trading_days = Column(Integer, default=0) best_pattern = Column(String, nullable=True) summary = Column(Text, nullable=True) improvements = Column(JSON, default=[]) goals_met = Column(JSON, default=[]) goals_missed = Column(JSON, default=[]) created_at = Column(DateTime(timezone=True), server_default=func.now())