from datetime import datetime from enum import Enum from typing import Optional, Dict, Any from dataclasses import dataclass from db.db_connection import create_client class PlanStatus(Enum): ACTIVE = 'active' ARCHIVED = 'archived' TESTING = 'testing' DEPRECATED = 'deprecated' class Timeframe(Enum): DAILY = 'daily' WEEKLY = 'weekly' HOURLY = 'hourly' MIN_15 = '15-min' MIN_30 = '30-min' MIN_5 = '5-min' class MarketFocus(Enum): STOCKS = 'stocks' CRYPTO = 'crypto' FOREX = 'forex' OPTIONS = 'options' FUTURES = 'futures' class TradeFrequency(Enum): DAILY = 'daily' WEEKLY = 'weekly' MONTHLY = 'monthly' AS_NEEDED = 'as-needed' @dataclass class TradingPlan: # General Info plan_name: str status: PlanStatus created_at: datetime = None updated_at: datetime = None id: int = None # Strategy Definition timeframe: Timeframe market_focus: MarketFocus entry_criteria: str exit_criteria: str stop_loss: float profit_target: float risk_reward_ratio: float trade_frequency: TradeFrequency market_conditions: str indicators_used: str # Trade Execution Rules entry_confirmation: str position_sizing: float maximum_drawdown: float max_trades_per_day: int max_trades_per_week: int # Risk Management total_risk_per_trade: float max_portfolio_risk: float adjustments_for_drawdown: str risk_controls: str # Performance Tracking win_rate: Optional[float] = None average_return_per_trade: Optional[float] = None profit_factor: Optional[float] = None historical_backtest_results: Optional[str] = None real_trade_performance: Optional[str] = None # Notes & Evolution improvements_needed: Optional[str] = None strategy_version: int = 1 plan_author: str trade_review_notes: Optional[str] = None future_testing_ideas: Optional[str] = None # Optional fields sector_focus: Optional[str] = None fundamental_criteria: Optional[str] = None options_strategy_details: Optional[str] = None def create_trading_plan_table(): """Create the trading plans table if it doesn't exist""" with create_client() as client: query = """ CREATE TABLE IF NOT EXISTS trading_plans ( id Int32, plan_name String, status String, created_at DateTime, updated_at DateTime, timeframe String, market_focus String, entry_criteria String, exit_criteria String, stop_loss Float64, profit_target Float64, risk_reward_ratio Float64, trade_frequency String, market_conditions String, indicators_used String, entry_confirmation String, position_sizing Float64, maximum_drawdown Float64, max_trades_per_day Int32, max_trades_per_week Int32, total_risk_per_trade Float64, max_portfolio_risk Float64, adjustments_for_drawdown String, risk_controls String, win_rate Nullable(Float64), average_return_per_trade Nullable(Float64), profit_factor Nullable(Float64), historical_backtest_results Nullable(String), real_trade_performance Nullable(String), improvements_needed Nullable(String), strategy_version Int32, plan_author String, trade_review_notes Nullable(String), future_testing_ideas Nullable(String), sector_focus Nullable(String), fundamental_criteria Nullable(String), options_strategy_details Nullable(String) ) ENGINE = MergeTree() ORDER BY (id, created_at) """ client.execute(query) def save_trading_plan(plan: TradingPlan) -> int: """Save a trading plan to the database""" with create_client() as client: if not plan.id: # Generate new ID for new plans result = client.execute("SELECT max(id) FROM trading_plans") plan.id = (result[0][0] or 0) + 1 plan.created_at = datetime.now() plan.updated_at = datetime.now() query = """ INSERT INTO trading_plans VALUES ( %(id)s, %(plan_name)s, %(status)s, %(created_at)s, %(updated_at)s, %(timeframe)s, %(market_focus)s, %(entry_criteria)s, %(exit_criteria)s, %(stop_loss)s, %(profit_target)s, %(risk_reward_ratio)s, %(trade_frequency)s, %(market_conditions)s, %(indicators_used)s, %(entry_confirmation)s, %(position_sizing)s, %(maximum_drawdown)s, %(max_trades_per_day)s, %(max_trades_per_week)s, %(total_risk_per_trade)s, %(max_portfolio_risk)s, %(adjustments_for_drawdown)s, %(risk_controls)s, %(win_rate)s, %(average_return_per_trade)s, %(profit_factor)s, %(historical_backtest_results)s, %(real_trade_performance)s, %(improvements_needed)s, %(strategy_version)s, %(plan_author)s, %(trade_review_notes)s, %(future_testing_ideas)s, %(sector_focus)s, %(fundamental_criteria)s, %(options_strategy_details)s ) """ params = { 'id': plan.id, 'plan_name': plan.plan_name, 'status': plan.status.value, 'created_at': plan.created_at, 'updated_at': plan.updated_at, 'timeframe': plan.timeframe.value, 'market_focus': plan.market_focus.value, 'entry_criteria': plan.entry_criteria, 'exit_criteria': plan.exit_criteria, 'stop_loss': plan.stop_loss, 'profit_target': plan.profit_target, 'risk_reward_ratio': plan.risk_reward_ratio, 'trade_frequency': plan.trade_frequency.value, 'market_conditions': plan.market_conditions, 'indicators_used': plan.indicators_used, 'entry_confirmation': plan.entry_confirmation, 'position_sizing': plan.position_sizing, 'maximum_drawdown': plan.maximum_drawdown, 'max_trades_per_day': plan.max_trades_per_day, 'max_trades_per_week': plan.max_trades_per_week, 'total_risk_per_trade': plan.total_risk_per_trade, 'max_portfolio_risk': plan.max_portfolio_risk, 'adjustments_for_drawdown': plan.adjustments_for_drawdown, 'risk_controls': plan.risk_controls, 'win_rate': plan.win_rate, 'average_return_per_trade': plan.average_return_per_trade, 'profit_factor': plan.profit_factor, 'historical_backtest_results': plan.historical_backtest_results, 'real_trade_performance': plan.real_trade_performance, 'improvements_needed': plan.improvements_needed, 'strategy_version': plan.strategy_version, 'plan_author': plan.plan_author, 'trade_review_notes': plan.trade_review_notes, 'future_testing_ideas': plan.future_testing_ideas, 'sector_focus': plan.sector_focus, 'fundamental_criteria': plan.fundamental_criteria, 'options_strategy_details': plan.options_strategy_details } client.execute(query, params) return plan.id