- Restructure tabs to analysis-focused workflow: * Analysis Hub: AI analysis, risk management, manual trade logger * Daily Prep: Market summary, alerts, checklist, news, trading plan * Journal & Review: Trading journal, habit tracker, advanced analytics * Live Charts: Technical analysis with streaming charts - Add ManualTradeLogger component for logging trades from MT5/TradingView/cTrader - Remove execution-focused components (TradeControls, PortfolioTracker) - Update XAU/USD price to realistic ,084.99 - Add indicator preferences and AI plan service - Add comprehensive documentation on decision coverage and implementation
224 lines
9.5 KiB
Python
224 lines
9.5 KiB
Python
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())
|
|
|
|
|
|
class UserIndicatorPreferences(Base):
|
|
"""User's preferred technical indicators for analysis and AI plan generation"""
|
|
__tablename__ = "user_indicator_preferences"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
user_id = Column(String, nullable=True)
|
|
indicator_name = Column(String) # SMA, EMA, RSI, MACD, BB, ATR, Stochastic, Fibonacci, VWAP, Pivot
|
|
enabled = Column(Boolean, default=True)
|
|
parameters = Column(JSON, nullable=True) # Indicator-specific parameters (e.g., period, length)
|
|
priority = Column(Integer, default=0) # Higher priority = more important in AI analysis
|
|
notes = Column(Text, nullable=True) # User notes about why they prefer this indicator
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|
|
|
|
|
|
class AIPlanGeneration(Base):
|
|
"""AI-generated daily trading plans"""
|
|
__tablename__ = "ai_plan_generations"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
user_id = Column(String, nullable=True)
|
|
plan_date = Column(Date, default=func.current_date())
|
|
|
|
# AI-generated plan details
|
|
market_bias = Column(String) # BULLISH, BEARISH, NEUTRAL
|
|
confidence = Column(Float) # 0-100
|
|
daily_target = Column(Float, nullable=True)
|
|
max_loss = Column(Float, nullable=True)
|
|
entry_zone_min = Column(Float, nullable=True)
|
|
entry_zone_max = Column(Float, nullable=True)
|
|
target_price = Column(Float, nullable=True)
|
|
stop_loss = Column(Float, nullable=True)
|
|
support_levels = Column(JSON, default=[]) # List of support prices
|
|
resistance_levels = Column(JSON, default=[]) # List of resistance prices
|
|
max_trades = Column(Integer, default=3)
|
|
trading_notes = Column(Text, nullable=True) # AI-generated strategy notes
|
|
|
|
# AI analysis metadata
|
|
indicators_used = Column(JSON, default=[]) # List of indicators used in analysis
|
|
reasoning = Column(Text, nullable=True) # AI's reasoning for the plan
|
|
market_conditions = Column(JSON, nullable=True) # Market data used in analysis
|
|
ai_model = Column(String, nullable=True) # Model used for generation
|
|
|
|
# User interaction
|
|
accepted = Column(Boolean, default=False) # User accepted this plan
|
|
modified = Column(Boolean, default=False) # User modified after generation
|
|
feedback = Column(Text, nullable=True) # User feedback on plan accuracy
|
|
|
|
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
|