180 lines
6.4 KiB
Python
180 lines
6.4 KiB
Python
"""
|
|
Configuration Settings
|
|
=====================
|
|
|
|
Central configuration for the autonomous trading system.
|
|
"""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from dotenv import load_dotenv
|
|
|
|
# Load environment variables
|
|
load_dotenv()
|
|
|
|
|
|
class Config:
|
|
"""Configuration class for autonomous trading system"""
|
|
|
|
# === IBKR Settings ===
|
|
IBKR_HOST = os.getenv('IBKR_HOST', '127.0.0.1')
|
|
IBKR_PORT = int(os.getenv('IBKR_PORT', 7497)) # 7497=paper, 7496=live
|
|
IBKR_CLIENT_ID = int(os.getenv('IBKR_CLIENT_ID', 1))
|
|
|
|
# === API Keys ===
|
|
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
|
|
ALPHA_VANTAGE_API_KEY = os.getenv('ALPHA_VANTAGE_API_KEY')
|
|
QUIVER_API_KEY = os.getenv('QUIVER_API_KEY')
|
|
POLYGON_API_KEY = os.getenv('POLYGON_API_KEY')
|
|
NEWS_API_KEY = os.getenv('NEWS_API_KEY')
|
|
|
|
# === Notification Settings ===
|
|
# Discord
|
|
DISCORD_WEBHOOK_URL = os.getenv('DISCORD_WEBHOOK_URL')
|
|
|
|
# Telegram
|
|
TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
|
|
TELEGRAM_CHAT_ID = os.getenv('TELEGRAM_CHAT_ID')
|
|
|
|
# Email
|
|
EMAIL_SMTP_SERVER = os.getenv('EMAIL_SMTP_SERVER', 'smtp.gmail.com')
|
|
EMAIL_SMTP_PORT = int(os.getenv('EMAIL_SMTP_PORT', 587))
|
|
EMAIL_SENDER = os.getenv('EMAIL_SENDER')
|
|
EMAIL_PASSWORD = os.getenv('EMAIL_PASSWORD')
|
|
EMAIL_RECIPIENT = os.getenv('EMAIL_RECIPIENT')
|
|
|
|
# === Portfolio Settings ===
|
|
# Your IBKR portfolio tickers
|
|
PORTFOLIO_TICKERS = [
|
|
"AVGO", # Broadcom - 43 shares
|
|
"MSFT", # Microsoft - 12 shares
|
|
"MU", # Micron - 13 shares
|
|
"NVDA", # Nvidia - 30 shares
|
|
"TSM", # Taiwan Semi - 15 shares
|
|
]
|
|
|
|
# Additional tickers to monitor
|
|
WATCHLIST = os.getenv('WATCHLIST', 'AAPL,TSLA,META,GOOGL,AMZN').split(',')
|
|
|
|
# === Trading Settings ===
|
|
TRADING_ENABLED = os.getenv('TRADING_ENABLED', 'false').lower() == 'true'
|
|
PAPER_TRADING = os.getenv('PAPER_TRADING', 'true').lower() == 'true'
|
|
|
|
# Risk Management
|
|
MAX_POSITION_SIZE = float(os.getenv('MAX_POSITION_SIZE', 0.20)) # 20% max per position
|
|
MAX_DAILY_LOSS = float(os.getenv('MAX_DAILY_LOSS', 0.05)) # 5% daily loss limit
|
|
MAX_TRADES_PER_DAY = int(os.getenv('MAX_TRADES_PER_DAY', 10))
|
|
STOP_LOSS_PERCENT = float(os.getenv('STOP_LOSS_PERCENT', 0.03)) # 3% stop loss
|
|
|
|
# Position Sizing
|
|
BASE_POSITION_SIZE = float(os.getenv('BASE_POSITION_SIZE', 0.10)) # 10% base
|
|
MIN_POSITION_SIZE = float(os.getenv('MIN_POSITION_SIZE', 0.05)) # 5% minimum
|
|
CONFIDENCE_THRESHOLD = float(os.getenv('CONFIDENCE_THRESHOLD', 70)) # Min 70% confidence
|
|
|
|
# === AI Model Settings ===
|
|
DEEP_THINK_MODEL = os.getenv('DEEP_THINK_MODEL', 'gpt-4o-mini')
|
|
QUICK_THINK_MODEL = os.getenv('QUICK_THINK_MODEL', 'gpt-4o-mini')
|
|
MAX_DEBATE_ROUNDS = int(os.getenv('MAX_DEBATE_ROUNDS', 1))
|
|
|
|
# === Schedule Settings (in minutes) ===
|
|
PORTFOLIO_CHECK_INTERVAL = int(os.getenv('PORTFOLIO_CHECK_INTERVAL', 5))
|
|
MARKET_SCAN_INTERVAL = int(os.getenv('MARKET_SCAN_INTERVAL', 15))
|
|
NEWS_CHECK_INTERVAL = int(os.getenv('NEWS_CHECK_INTERVAL', 30))
|
|
CONGRESS_CHECK_INTERVAL = int(os.getenv('CONGRESS_CHECK_INTERVAL', 60))
|
|
RISK_CHECK_INTERVAL = int(os.getenv('RISK_CHECK_INTERVAL', 30))
|
|
|
|
# === Database Settings ===
|
|
DB_HOST = os.getenv('DB_HOST', 'localhost')
|
|
DB_PORT = int(os.getenv('DB_PORT', 5432))
|
|
DB_NAME = os.getenv('DB_NAME', 'trading_autonomous')
|
|
DB_USER = os.getenv('DB_USER', 'trader')
|
|
DB_PASSWORD = os.getenv('DB_PASSWORD', 'password')
|
|
|
|
@classmethod
|
|
def get_db_url(cls):
|
|
"""Get database connection URL"""
|
|
return f"postgresql://{cls.DB_USER}:{cls.DB_PASSWORD}@{cls.DB_HOST}:{cls.DB_PORT}/{cls.DB_NAME}"
|
|
|
|
@classmethod
|
|
def to_dict(cls):
|
|
"""Convert config to dictionary"""
|
|
return {
|
|
# IBKR
|
|
'ibkr_host': cls.IBKR_HOST,
|
|
'ibkr_port': cls.IBKR_PORT,
|
|
'ibkr_client_id': cls.IBKR_CLIENT_ID,
|
|
|
|
# API Keys
|
|
'openai_api_key': cls.OPENAI_API_KEY,
|
|
'alpha_vantage_api_key': cls.ALPHA_VANTAGE_API_KEY,
|
|
'quiver_api_key': cls.QUIVER_API_KEY,
|
|
|
|
# Notifications
|
|
'discord_webhook_url': cls.DISCORD_WEBHOOK_URL,
|
|
'telegram_bot_token': cls.TELEGRAM_BOT_TOKEN,
|
|
'telegram_chat_id': cls.TELEGRAM_CHAT_ID,
|
|
'email': {
|
|
'smtp_server': cls.EMAIL_SMTP_SERVER,
|
|
'smtp_port': cls.EMAIL_SMTP_PORT,
|
|
'sender_email': cls.EMAIL_SENDER,
|
|
'sender_password': cls.EMAIL_PASSWORD,
|
|
'recipient_email': cls.EMAIL_RECIPIENT
|
|
},
|
|
|
|
# Portfolio
|
|
'portfolio_tickers': cls.PORTFOLIO_TICKERS,
|
|
'watchlist': cls.WATCHLIST,
|
|
|
|
# Trading
|
|
'trading_enabled': cls.TRADING_ENABLED,
|
|
'paper_trading': cls.PAPER_TRADING,
|
|
'max_position_size': cls.MAX_POSITION_SIZE,
|
|
'confidence_threshold': cls.CONFIDENCE_THRESHOLD,
|
|
|
|
# AI Models
|
|
'deep_think_llm': cls.DEEP_THINK_MODEL,
|
|
'quick_think_llm': cls.QUICK_THINK_MODEL,
|
|
'max_debate_rounds': cls.MAX_DEBATE_ROUNDS
|
|
}
|
|
|
|
@classmethod
|
|
def validate(cls):
|
|
"""Validate configuration"""
|
|
errors = []
|
|
|
|
# Check required API keys
|
|
if not cls.OPENAI_API_KEY:
|
|
errors.append("OPENAI_API_KEY is required")
|
|
|
|
if not cls.ALPHA_VANTAGE_API_KEY:
|
|
errors.append("ALPHA_VANTAGE_API_KEY is required")
|
|
|
|
# Check notification settings
|
|
if not any([cls.DISCORD_WEBHOOK_URL, cls.TELEGRAM_BOT_TOKEN, cls.EMAIL_SENDER]):
|
|
errors.append("At least one notification method must be configured")
|
|
|
|
# Validate risk settings
|
|
if cls.MAX_POSITION_SIZE > 0.5:
|
|
errors.append("MAX_POSITION_SIZE should not exceed 50%")
|
|
|
|
if cls.MAX_DAILY_LOSS > 0.1:
|
|
errors.append("MAX_DAILY_LOSS should not exceed 10%")
|
|
|
|
if errors:
|
|
print("Configuration errors:")
|
|
for error in errors:
|
|
print(f" - {error}")
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
# Example config validation
|
|
if __name__ == "__main__":
|
|
if Config.validate():
|
|
print("✅ Configuration valid")
|
|
print(f"Portfolio: {Config.PORTFOLIO_TICKERS}")
|
|
print(f"Trading: {'ENABLED' if Config.TRADING_ENABLED else 'DISABLED'}")
|
|
print(f"Mode: {'PAPER' if Config.PAPER_TRADING else 'LIVE'}")
|
|
else:
|
|
print("❌ Configuration invalid") |