541 lines
12 KiB
Python
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
|