2025-06-02 13:27:01 +08:00
|
|
|
"""
|
|
|
|
|
Database Operations Module
|
|
|
|
|
|
2025-06-06 21:54:45 +08:00
|
|
|
This module provides a centralized `DatabaseOperations` class that serves as the
|
|
|
|
|
main entry point for all database interactions. It follows the Repository pattern
|
|
|
|
|
by composing individual repository classes, each responsible for a specific table.
|
2025-06-02 13:27:01 +08:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import logging
|
2025-06-06 21:54:45 +08:00
|
|
|
from typing import Optional, Dict, Any
|
2025-06-02 13:27:01 +08:00
|
|
|
from sqlalchemy import text
|
|
|
|
|
|
2025-06-06 21:54:45 +08:00
|
|
|
from .repositories import (
|
|
|
|
|
BotRepository,
|
|
|
|
|
MarketDataRepository,
|
|
|
|
|
RawTradeRepository,
|
4.0 - 3.0 Implement strategy analysis tables and repository for backtesting
- Added `StrategyRun` and `StrategySignal` models to track strategy execution sessions and generated signals, respectively, ensuring a clear separation from live trading data.
- Introduced `StrategyRepository` for managing database operations related to strategy runs and signals, including methods for creating, updating, and retrieving strategy data.
- Updated `DatabaseOperations` to integrate the new repository, enhancing the overall architecture and maintaining consistency with existing database access patterns.
- Enhanced documentation to reflect the new database schema and repository functionalities, ensuring clarity for future development and usage.
These changes establish a robust foundation for strategy analysis and backtesting, aligning with project goals for modularity, performance, and maintainability.
2025-06-12 15:29:14 +08:00
|
|
|
StrategyRepository,
|
2025-06-06 21:54:45 +08:00
|
|
|
DatabaseOperationError,
|
|
|
|
|
)
|
2025-06-02 13:27:01 +08:00
|
|
|
|
|
|
|
|
class DatabaseOperations:
|
|
|
|
|
"""
|
|
|
|
|
Main database operations manager that provides access to all repositories.
|
|
|
|
|
|
|
|
|
|
This is the main entry point for database operations, providing a
|
|
|
|
|
centralized interface to all table-specific repositories.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, logger: Optional[logging.Logger] = None):
|
|
|
|
|
"""Initialize database operations with optional logger."""
|
|
|
|
|
self.logger = logger
|
|
|
|
|
|
|
|
|
|
# Initialize repositories
|
2025-06-06 21:54:45 +08:00
|
|
|
self.bots = BotRepository(logger)
|
2025-06-02 13:27:01 +08:00
|
|
|
self.market_data = MarketDataRepository(logger)
|
|
|
|
|
self.raw_trades = RawTradeRepository(logger)
|
4.0 - 3.0 Implement strategy analysis tables and repository for backtesting
- Added `StrategyRun` and `StrategySignal` models to track strategy execution sessions and generated signals, respectively, ensuring a clear separation from live trading data.
- Introduced `StrategyRepository` for managing database operations related to strategy runs and signals, including methods for creating, updating, and retrieving strategy data.
- Updated `DatabaseOperations` to integrate the new repository, enhancing the overall architecture and maintaining consistency with existing database access patterns.
- Enhanced documentation to reflect the new database schema and repository functionalities, ensuring clarity for future development and usage.
These changes establish a robust foundation for strategy analysis and backtesting, aligning with project goals for modularity, performance, and maintainability.
2025-06-12 15:29:14 +08:00
|
|
|
self.strategies = StrategyRepository(logger)
|
2025-06-02 13:27:01 +08:00
|
|
|
|
|
|
|
|
def health_check(self) -> bool:
|
|
|
|
|
"""
|
|
|
|
|
Perform a health check on database connections.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
True if database is healthy, False otherwise
|
|
|
|
|
"""
|
|
|
|
|
try:
|
2025-06-06 21:54:45 +08:00
|
|
|
# We use one of the repositories to get a session
|
2025-06-02 13:27:01 +08:00
|
|
|
with self.market_data.get_session() as session:
|
|
|
|
|
result = session.execute(text("SELECT 1"))
|
|
|
|
|
return result.fetchone() is not None
|
|
|
|
|
except Exception as e:
|
|
|
|
|
if self.logger:
|
|
|
|
|
self.logger.error(f"Database health check failed: {e}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def get_stats(self) -> Dict[str, Any]:
|
|
|
|
|
"""
|
|
|
|
|
Get database statistics.
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
Dictionary containing database statistics
|
|
|
|
|
"""
|
|
|
|
|
try:
|
|
|
|
|
stats = {
|
|
|
|
|
'healthy': self.health_check(),
|
|
|
|
|
'repositories': {
|
2025-06-06 21:54:45 +08:00
|
|
|
'bots': 'BotRepository',
|
2025-06-02 13:27:01 +08:00
|
|
|
'market_data': 'MarketDataRepository',
|
4.0 - 3.0 Implement strategy analysis tables and repository for backtesting
- Added `StrategyRun` and `StrategySignal` models to track strategy execution sessions and generated signals, respectively, ensuring a clear separation from live trading data.
- Introduced `StrategyRepository` for managing database operations related to strategy runs and signals, including methods for creating, updating, and retrieving strategy data.
- Updated `DatabaseOperations` to integrate the new repository, enhancing the overall architecture and maintaining consistency with existing database access patterns.
- Enhanced documentation to reflect the new database schema and repository functionalities, ensuring clarity for future development and usage.
These changes establish a robust foundation for strategy analysis and backtesting, aligning with project goals for modularity, performance, and maintainability.
2025-06-12 15:29:14 +08:00
|
|
|
'raw_trades': 'RawTradeRepository',
|
|
|
|
|
'strategies': 'StrategyRepository'
|
2025-06-02 13:27:01 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 21:54:45 +08:00
|
|
|
# Use a single session for all counts for efficiency
|
2025-06-02 13:27:01 +08:00
|
|
|
with self.market_data.get_session() as session:
|
2025-06-06 21:54:45 +08:00
|
|
|
stats['bot_count'] = session.execute(text("SELECT COUNT(*) FROM bots")).scalar_one()
|
|
|
|
|
stats['candle_count'] = session.execute(text("SELECT COUNT(*) FROM market_data")).scalar_one()
|
|
|
|
|
stats['raw_trade_count'] = session.execute(text("SELECT COUNT(*) FROM raw_trades")).scalar_one()
|
4.0 - 3.0 Implement strategy analysis tables and repository for backtesting
- Added `StrategyRun` and `StrategySignal` models to track strategy execution sessions and generated signals, respectively, ensuring a clear separation from live trading data.
- Introduced `StrategyRepository` for managing database operations related to strategy runs and signals, including methods for creating, updating, and retrieving strategy data.
- Updated `DatabaseOperations` to integrate the new repository, enhancing the overall architecture and maintaining consistency with existing database access patterns.
- Enhanced documentation to reflect the new database schema and repository functionalities, ensuring clarity for future development and usage.
These changes establish a robust foundation for strategy analysis and backtesting, aligning with project goals for modularity, performance, and maintainability.
2025-06-12 15:29:14 +08:00
|
|
|
stats['strategy_runs_count'] = session.execute(text("SELECT COUNT(*) FROM strategy_runs")).scalar_one()
|
|
|
|
|
stats['strategy_signals_count'] = session.execute(text("SELECT COUNT(*) FROM strategy_signals")).scalar_one()
|
2025-06-02 13:27:01 +08:00
|
|
|
|
|
|
|
|
return stats
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
if self.logger:
|
|
|
|
|
self.logger.error(f"Error getting database stats: {e}")
|
|
|
|
|
return {'healthy': False, 'error': str(e)}
|
|
|
|
|
|
|
|
|
|
# Singleton instance for global access
|
|
|
|
|
_db_operations_instance: Optional[DatabaseOperations] = None
|
|
|
|
|
|
|
|
|
|
def get_database_operations(logger: Optional[logging.Logger] = None) -> DatabaseOperations:
|
|
|
|
|
"""
|
|
|
|
|
Get the global database operations instance.
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
logger: Optional logger for database operations
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
DatabaseOperations instance
|
|
|
|
|
"""
|
|
|
|
|
global _db_operations_instance
|
|
|
|
|
if _db_operations_instance is None:
|
|
|
|
|
_db_operations_instance = DatabaseOperations(logger)
|
2025-06-06 21:54:45 +08:00
|
|
|
return _db_operations_instance
|