Local changes: Updated model training, removed debug instrumentation, and configuration improvements
This commit is contained in:
1
backend/core/__init__.py
Normal file
1
backend/core/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Core backend utilities."""
|
||||
70
backend/core/dependencies.py
Normal file
70
backend/core/dependencies.py
Normal file
@@ -0,0 +1,70 @@
|
||||
"""FastAPI dependencies for service injection."""
|
||||
|
||||
from functools import lru_cache
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add src to path - must be done before any imports
|
||||
src_path = Path(__file__).parent.parent.parent / "src"
|
||||
if str(src_path) not in sys.path:
|
||||
sys.path.insert(0, str(src_path))
|
||||
|
||||
# Import database and redis immediately
|
||||
from core.database import get_database as _get_database
|
||||
from src.core.redis import get_redis_client as _get_redis_client
|
||||
|
||||
# Lazy imports for other services (only import when needed to avoid import errors)
|
||||
# These will be imported on-demand in their respective getter functions
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_database():
|
||||
"""Get database instance."""
|
||||
return _get_database()
|
||||
|
||||
|
||||
async def get_db_session():
|
||||
"""Get database session."""
|
||||
db = get_database()
|
||||
async with db.get_session() as session:
|
||||
yield session
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_trading_engine():
|
||||
"""Get trading engine instance."""
|
||||
from trading.engine import get_trading_engine as _get_trading_engine
|
||||
return _get_trading_engine()
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_portfolio_tracker():
|
||||
"""Get portfolio tracker instance."""
|
||||
from portfolio.tracker import get_portfolio_tracker as _get_portfolio_tracker
|
||||
return _get_portfolio_tracker()
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_strategy_registry():
|
||||
"""Get strategy registry instance."""
|
||||
from strategies.base import get_strategy_registry as _get_strategy_registry
|
||||
return _get_strategy_registry()
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_backtesting_engine():
|
||||
"""Get backtesting engine instance."""
|
||||
from backtesting.engine import get_backtest_engine as _get_backtesting_engine
|
||||
return _get_backtesting_engine()
|
||||
|
||||
|
||||
def get_exchange_factory():
|
||||
"""Get exchange factory."""
|
||||
from exchanges.factory import ExchangeFactory
|
||||
return ExchangeFactory
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_redis_client():
|
||||
"""Get Redis client instance."""
|
||||
return _get_redis_client()
|
||||
213
backend/core/schemas.py
Normal file
213
backend/core/schemas.py
Normal file
@@ -0,0 +1,213 @@
|
||||
"""Pydantic schemas for request/response validation."""
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from decimal import Decimal
|
||||
from typing import Optional, List, Dict, Any
|
||||
from pydantic import BaseModel, Field, ConfigDict, field_validator
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class OrderSide(str, Enum):
|
||||
"""Order side."""
|
||||
BUY = "buy"
|
||||
SELL = "sell"
|
||||
|
||||
|
||||
class OrderType(str, Enum):
|
||||
"""Order type."""
|
||||
MARKET = "market"
|
||||
LIMIT = "limit"
|
||||
STOP_LOSS = "stop_loss"
|
||||
TAKE_PROFIT = "take_profit"
|
||||
TRAILING_STOP = "trailing_stop"
|
||||
OCO = "oco"
|
||||
ICEBERG = "iceberg"
|
||||
|
||||
|
||||
class OrderStatus(str, Enum):
|
||||
"""Order status."""
|
||||
PENDING = "pending"
|
||||
OPEN = "open"
|
||||
PARTIALLY_FILLED = "partially_filled"
|
||||
FILLED = "filled"
|
||||
CANCELLED = "cancelled"
|
||||
REJECTED = "rejected"
|
||||
EXPIRED = "expired"
|
||||
|
||||
|
||||
# Trading Schemas
|
||||
class OrderCreate(BaseModel):
|
||||
"""Create order request."""
|
||||
exchange_id: int
|
||||
symbol: str
|
||||
side: OrderSide
|
||||
order_type: OrderType
|
||||
quantity: Decimal
|
||||
price: Optional[Decimal] = None
|
||||
strategy_id: Optional[int] = None
|
||||
paper_trading: bool = True
|
||||
|
||||
|
||||
class OrderResponse(BaseModel):
|
||||
"""Order response."""
|
||||
model_config = ConfigDict(from_attributes=True, populate_by_name=True)
|
||||
|
||||
id: int
|
||||
exchange_id: int
|
||||
strategy_id: Optional[int]
|
||||
symbol: str
|
||||
order_type: OrderType
|
||||
side: OrderSide
|
||||
status: OrderStatus
|
||||
quantity: Decimal
|
||||
price: Optional[Decimal]
|
||||
filled_quantity: Decimal
|
||||
average_fill_price: Optional[Decimal]
|
||||
fee: Decimal
|
||||
paper_trading: bool
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
filled_at: Optional[datetime]
|
||||
|
||||
@field_validator('created_at', 'updated_at', 'filled_at', mode='after')
|
||||
@classmethod
|
||||
def ensure_utc(cls, v: Optional[datetime]) -> Optional[datetime]:
|
||||
if v and v.tzinfo is None:
|
||||
return v.replace(tzinfo=timezone.utc)
|
||||
return v
|
||||
|
||||
|
||||
class PositionResponse(BaseModel):
|
||||
"""Position response."""
|
||||
model_config = ConfigDict(from_attributes=True, populate_by_name=True)
|
||||
|
||||
symbol: str
|
||||
quantity: Decimal
|
||||
entry_price: Decimal
|
||||
current_price: Decimal
|
||||
unrealized_pnl: Decimal
|
||||
realized_pnl: Decimal
|
||||
|
||||
|
||||
# Portfolio Schemas
|
||||
class PortfolioResponse(BaseModel):
|
||||
"""Portfolio response."""
|
||||
positions: List[Dict[str, Any]]
|
||||
performance: Dict[str, float]
|
||||
timestamp: str
|
||||
|
||||
|
||||
class PortfolioHistoryResponse(BaseModel):
|
||||
"""Portfolio history response."""
|
||||
dates: List[str]
|
||||
values: List[float]
|
||||
pnl: List[float]
|
||||
|
||||
|
||||
# Strategy Schemas
|
||||
class StrategyCreate(BaseModel):
|
||||
"""Create strategy request."""
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
strategy_type: str
|
||||
class_name: str
|
||||
parameters: Dict[str, Any] = Field(default_factory=dict)
|
||||
timeframes: List[str] = Field(default_factory=lambda: ["1h"])
|
||||
paper_trading: bool = True
|
||||
schedule: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class StrategyUpdate(BaseModel):
|
||||
"""Update strategy request."""
|
||||
name: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
parameters: Optional[Dict[str, Any]] = None
|
||||
timeframes: Optional[List[str]] = None
|
||||
enabled: Optional[bool] = None
|
||||
schedule: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
class StrategyResponse(BaseModel):
|
||||
"""Strategy response."""
|
||||
model_config = ConfigDict(from_attributes=True, populate_by_name=True)
|
||||
|
||||
id: int
|
||||
name: str
|
||||
description: Optional[str]
|
||||
strategy_type: str
|
||||
class_name: str
|
||||
parameters: Dict[str, Any]
|
||||
timeframes: List[str]
|
||||
enabled: bool
|
||||
running: bool = False
|
||||
paper_trading: bool
|
||||
version: str
|
||||
schedule: Optional[Dict[str, Any]]
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
@field_validator('created_at', 'updated_at', mode='after')
|
||||
@classmethod
|
||||
def ensure_utc(cls, v: Optional[datetime]) -> Optional[datetime]:
|
||||
if v and v.tzinfo is None:
|
||||
return v.replace(tzinfo=timezone.utc)
|
||||
return v
|
||||
|
||||
|
||||
# Backtesting Schemas
|
||||
class BacktestRequest(BaseModel):
|
||||
"""Backtest request."""
|
||||
strategy_id: int
|
||||
symbol: str
|
||||
exchange: str
|
||||
timeframe: str
|
||||
start_date: datetime
|
||||
end_date: datetime
|
||||
initial_capital: Decimal = Decimal("100.0")
|
||||
slippage: float = 0.001
|
||||
fee_rate: float = 0.001
|
||||
|
||||
|
||||
class BacktestResponse(BaseModel):
|
||||
"""Backtest response."""
|
||||
backtest_id: Optional[int] = None
|
||||
results: Dict[str, Any]
|
||||
status: str = "completed"
|
||||
|
||||
|
||||
# Exchange Schemas
|
||||
class ExchangeResponse(BaseModel):
|
||||
"""Exchange response."""
|
||||
model_config = ConfigDict(from_attributes=True, populate_by_name=True)
|
||||
|
||||
id: int
|
||||
name: str
|
||||
sandbox: bool
|
||||
read_only: bool
|
||||
enabled: bool
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
@field_validator('created_at', 'updated_at', mode='after')
|
||||
@classmethod
|
||||
def ensure_utc(cls, v: Optional[datetime]) -> Optional[datetime]:
|
||||
if v and v.tzinfo is None:
|
||||
return v.replace(tzinfo=timezone.utc)
|
||||
return v
|
||||
|
||||
|
||||
# WebSocket Messages
|
||||
class PriceUpdate(BaseModel):
|
||||
"""Price update message."""
|
||||
exchange: str
|
||||
symbol: str
|
||||
price: Decimal
|
||||
timestamp: datetime
|
||||
|
||||
|
||||
class OrderUpdate(BaseModel):
|
||||
"""Order update message."""
|
||||
order_id: int
|
||||
status: OrderStatus
|
||||
filled_quantity: Optional[Decimal] = None
|
||||
timestamp: datetime
|
||||
Reference in New Issue
Block a user