Files
robinhood/backend/app/schemas/schemas.py
T

541 lines
12 KiB
Python

from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
from enum import Enum
class TradeAction(str, Enum):
BUY = "BUY"
SELL = "SELL"
class Recommendation(str, Enum):
BUY = "BUY"
SELL = "SELL"
HOLD = "HOLD"
class RiskLevel(str, Enum):
LOW = "LOW"
MEDIUM = "MEDIUM"
HIGH = "HIGH"
class PriceData(BaseModel):
time: int
open: float
high: float
low: float
close: float
volume: Optional[float] = None
class TradeCreate(BaseModel):
action: TradeAction
quantity: float
price: float
class TradeResponse(BaseModel):
id: int
simulation_id: int
action: TradeAction
quantity: float
price: float
total: float
pnl: Optional[float] = None
timestamp: datetime
class Config:
from_attributes = True
class PositionResponse(BaseModel):
symbol: str
quantity: float
avg_price: float
current_price: float
unrealized_pnl: float
unrealized_pnl_percent: float
class Config:
from_attributes = True
class PortfolioResponse(BaseModel):
cash: float
initial_capital: float
total_value: float
total_pnl: float
total_pnl_percent: float
position: Optional[PositionResponse] = None
trades: List[TradeResponse] = []
class MarketDataResponse(BaseModel):
symbol: str = "XAU/USD"
price: float
change: float
change_percent: float
high_24h: float
low_24h: float
volume: float
class SupportResistance(BaseModel):
support: List[float] = []
resistance: List[float] = []
class AIAnalysisRequest(BaseModel):
price_data: List[PriceData]
indicators: List[dict]
current_price: float
class AIAnalysisResponse(BaseModel):
recommendation: Recommendation
confidence: float = Field(..., ge=0, le=100)
reasoning: str
support_resistance: SupportResistance
risk_level: RiskLevel
class IndicatorData(BaseModel):
time: int
value: float
# News and Sentiment Schemas
class Sentiment(str, Enum):
POSITIVE = "POSITIVE"
NEGATIVE = "NEGATIVE"
NEUTRAL = "NEUTRAL"
class NewsArticle(BaseModel):
id: str
source: str
title: str
description: Optional[str] = None
url: str
published_at: datetime
sentiment: Sentiment
sentiment_score: float = Field(..., ge=-1, le=1)
impact_on_gold: str # HIGH, MEDIUM, LOW
relevance_score: float = Field(..., ge=0, le=1)
category: str # MONETARY_POLICY, GEOPOLITICS, ECONOMIC_DATA, etc.
class NewsFeedResponse(BaseModel):
articles: List[NewsArticle]
total_count: int
bullish_count: int
bearish_count: int
neutral_count: int
overall_sentiment: Sentiment
avg_sentiment_score: float
class EconomicEvent(BaseModel):
id: str
title: str
country: str
currency: str
event_date: datetime
importance: str # HIGH, MEDIUM, LOW
forecast: Optional[str] = None
previous: Optional[str] = None
actual: Optional[str] = None
impact_on_gold: str
class EconomicCalendarResponse(BaseModel):
events: List[EconomicEvent]
upcoming_high_impact: int
# Alert Schemas
class AlertType(str, Enum):
PRICE_SPIKE = "PRICE_SPIKE"
PRICE_DROP = "PRICE_DROP"
NEWS_BREAKING = "NEWS_BREAKING"
SUPPORT_BREACH = "SUPPORT_BREACH"
RESISTANCE_BREACH = "RESISTANCE_BREACH"
HIGH_VOLATILITY = "HIGH_VOLATILITY"
ECONOMIC_EVENT = "ECONOMIC_EVENT"
class AlertSeverity(str, Enum):
CRITICAL = "CRITICAL"
HIGH = "HIGH"
MEDIUM = "MEDIUM"
LOW = "LOW"
class Alert(BaseModel):
id: str
type: AlertType
severity: AlertSeverity
title: str
message: str
price: Optional[float] = None
change_percent: Optional[float] = None
timestamp: datetime
related_news: Optional[List[str]] = [] # URLs to related news
action_required: bool = False
class AlertsResponse(BaseModel):
alerts: List[Alert]
critical_count: int
unread_count: int
# News-Price Correlation
class NewsPriceCorrelation(BaseModel):
news_id: str
news_title: str
news_time: datetime
price_before: float
price_after: float
price_change: float
price_change_percent: float
time_delta_minutes: int
correlation_strength: str # STRONG, MODERATE, WEAK
class CorrelationAnalysisResponse(BaseModel):
correlations: List[NewsPriceCorrelation]
significant_events: int
avg_price_impact: float
# Phase 1: Daily Helper Schemas
class UserProfileCreate(BaseModel):
email: Optional[str] = None
username: Optional[str] = None
timezone: str = "UTC"
preferred_trading_start: str = "09:00"
preferred_trading_end: str = "17:00"
risk_tolerance: str = "moderate"
trading_style: str = "day_trader"
daily_target: Optional[float] = None
max_loss: Optional[float] = None
class UserProfileUpdate(BaseModel):
timezone: Optional[str] = None
preferred_trading_start: Optional[str] = None
preferred_trading_end: Optional[str] = None
risk_tolerance: Optional[str] = None
trading_style: Optional[str] = None
daily_target: Optional[float] = None
max_loss: Optional[float] = None
notifications_enabled: Optional[bool] = None
email_reports: Optional[bool] = None
sms_enabled: Optional[bool] = None
push_notifications: Optional[bool] = None
phone_number: Optional[str] = None
class UserProfileResponse(BaseModel):
id: int
email: Optional[str]
username: Optional[str]
timezone: str
preferred_trading_start: str
preferred_trading_end: str
risk_tolerance: str
trading_style: str
daily_target: Optional[float]
max_loss: Optional[float]
notifications_enabled: bool
email_reports: bool
sms_enabled: bool
push_notifications: bool
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class DailyRoutineCreate(BaseModel):
routine_type: str # morning, active_trading, evening
scheduled_time: str # HH:MM
tasks: List[str] = []
enabled: bool = True
class DailyRoutineUpdate(BaseModel):
scheduled_time: Optional[str] = None
tasks: Optional[List[str]] = None
enabled: Optional[bool] = None
class DailyRoutineResponse(BaseModel):
id: int
routine_type: str
scheduled_time: str
tasks: List[str]
enabled: bool
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class RoutineExecutionResponse(BaseModel):
id: int
routine_id: int
executed_at: datetime
completion_status: str
tasks_completed: List[str]
execution_notes: Optional[str]
class Config:
from_attributes = True
class NotificationCreate(BaseModel):
notification_type: str
title: str
message: str
priority: str = "normal"
delivery_method: str = "push"
data: Optional[dict] = None
class NotificationResponse(BaseModel):
id: int
notification_type: str
title: str
message: str
priority: str
delivery_method: str
read: bool
created_at: datetime
read_at: Optional[datetime]
class Config:
from_attributes = True
class NotificationListResponse(BaseModel):
notifications: List[NotificationResponse]
unread_count: int
total_count: int
class ChecklistItem(BaseModel):
id: str
title: str
completed: bool = False
completed_at: Optional[datetime] = None
class DailyChecklistCreate(BaseModel):
checklist_type: str # morning, active_trading, evening, all
items: Optional[List[ChecklistItem]] = None
notes: Optional[str] = None
class DailyChecklistUpdate(BaseModel):
items: Optional[List[ChecklistItem]] = None
notes: Optional[str] = None
class DailyChecklistResponse(BaseModel):
id: int
checklist_date: str # ISO date string
checklist_type: str
items: List[ChecklistItem]
completion_percentage: float
notes: Optional[str]
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class HabitTrackerCreate(BaseModel):
habit_name: str
frequency: str = "daily" # daily, weekly
class HabitTrackerResponse(BaseModel):
id: int
habit_name: str
frequency: str
current_streak: int
longest_streak: int
total_completions: int
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class HabitCompletionRequest(BaseModel):
habit_id: int
completion_date: Optional[str] = None # ISO date string, defaults to today
# Phase 3: Advanced Analytics Schemas
class PerformanceSnapshotCreate(BaseModel):
snapshot_date: Optional[str] = None # ISO date, defaults to today
daily_pnl: float
daily_pnl_percent: float
total_trades: int
winning_trades: int
losing_trades: int
win_rate: float
best_trade: Optional[float] = None
worst_trade: Optional[float] = None
avg_win: Optional[float] = None
avg_loss: Optional[float] = None
sharpe_ratio: Optional[float] = None
profit_factor: Optional[float] = None
max_drawdown: Optional[float] = None
cumulative_pnl: float
portfolio_value: Optional[float] = None
class PerformanceSnapshotResponse(BaseModel):
id: int
snapshot_date: str
daily_pnl: float
daily_pnl_percent: float
total_trades: int
winning_trades: int
losing_trades: int
win_rate: float
best_trade: Optional[float]
worst_trade: Optional[float]
avg_win: Optional[float]
avg_loss: Optional[float]
sharpe_ratio: Optional[float]
profit_factor: Optional[float]
max_drawdown: Optional[float]
cumulative_pnl: float
portfolio_value: Optional[float]
created_at: datetime
class Config:
from_attributes = True
class TradePatternCreate(BaseModel):
pattern_name: str
description: Optional[str] = None
win_rate: float
avg_win: float
avg_loss: float
sample_count: int
best_timeframe: Optional[str] = None
best_time_of_day: Optional[str] = None
confidence_score: float
indicators_used: List[str] = []
market_conditions: Optional[str] = None
class TradePatternResponse(BaseModel):
id: int
pattern_name: str
description: Optional[str]
win_rate: float
avg_win: float
avg_loss: float
sample_count: int
best_timeframe: Optional[str]
best_time_of_day: Optional[str]
confidence_score: float
indicators_used: List[str]
market_conditions: Optional[str]
total_profit: float
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class LessonLearnedCreate(BaseModel):
category: str # entry, exit, risk, psychology, market
lesson_text: str
related_trades: List[int] = []
impact: str = "neutral" # positive, negative, neutral
tags: List[str] = []
importance: str = "helpful" # critical, important, helpful
class LessonLearnedResponse(BaseModel):
id: int
date_learned: datetime
category: str
lesson_text: str
related_trades: List[int]
impact: str
tags: List[str]
importance: str
status: str
created_at: datetime
class Config:
from_attributes = True
class MonthlyReviewCreate(BaseModel):
year: int
month: int
total_trades: int
total_pnl: float
total_pnl_percent: float
best_day: Optional[str] = None # ISO date
worst_day: Optional[str] = None
best_trade: Optional[float] = None
worst_trade: Optional[float] = None
win_rate: float
avg_daily_pnl: Optional[float] = None
sharpe_ratio: Optional[float] = None
max_drawdown: Optional[float] = None
trading_days: int
best_pattern: Optional[str] = None
summary: Optional[str] = None
improvements: List[str] = []
goals_met: List[str] = []
goals_missed: List[str] = []
class MonthlyReviewResponse(BaseModel):
id: int
year: int
month: int
total_trades: int
total_pnl: float
total_pnl_percent: float
best_day: Optional[str]
worst_day: Optional[str]
best_trade: Optional[float]
worst_trade: Optional[float]
win_rate: float
avg_daily_pnl: Optional[float]
sharpe_ratio: Optional[float]
max_drawdown: Optional[float]
trading_days: int
best_pattern: Optional[str]
summary: Optional[str]
improvements: List[str]
goals_met: List[str]
goals_missed: List[str]
created_at: datetime
class Config:
from_attributes = True