Spaces:
Runtime error
Runtime error
| # ============================================================ | |
| # PORTFOLIO INTELLIGENCE ENGINE - FULL APP.PY | |
| # Live + Historical Data Enabled | |
| # ============================================================ | |
| import yfinance as yf | |
| import numpy as np | |
| import pandas as pd | |
| from datetime import datetime, timedelta | |
| from scipy.optimize import minimize | |
| from scipy import stats | |
| from dataclasses import dataclass | |
| from typing import Dict, List | |
| import warnings | |
| warnings.filterwarnings("ignore") | |
| # ============================================================ | |
| # DATA ENGINE | |
| # ============================================================ | |
| class MarketDataLoader: | |
| def __init__(self, lookback_days=365, interval="1d"): | |
| self.lookback_days = lookback_days | |
| self.interval = interval | |
| def fetch(self, symbols: List[str]) -> Dict[str, pd.DataFrame]: | |
| end = datetime.now() | |
| start = end - timedelta(days=self.lookback_days) | |
| data = {} | |
| for s in symbols: | |
| df = yf.download( | |
| s, | |
| start=start.strftime("%Y-%m-%d"), | |
| end=end.strftime("%Y-%m-%d"), | |
| interval=self.interval, | |
| auto_adjust=True, | |
| progress=False | |
| ) | |
| if not df.empty: | |
| data[s] = df[["Open", "High", "Low", "Close", "Volume"]].dropna() | |
| return data | |
| # ============================================================ | |
| # AI FORECAST ENGINE (PROXY) | |
| # ============================================================ | |
| class SimpleAIForecaster: | |
| def forecast(self, prices: pd.Series, horizon=30) -> Dict: | |
| returns = np.log(prices / prices.shift(1)).dropna() | |
| mu = returns.mean() * horizon | |
| sigma = returns.std() * np.sqrt(horizon) | |
| samples = np.random.normal(mu, sigma, 1000) | |
| return { | |
| "samples": samples, | |
| "expected_return": mu, | |
| "confidence": float(np.clip(1 / (1 + sigma * 10), 0.3, 0.9)) | |
| } | |
| # ============================================================ | |
| # REGIME DETECTOR | |
| # ============================================================ | |
| class RegimeDetector: | |
| def detect(self, returns: pd.Series) -> Dict: | |
| vol = returns.std() * np.sqrt(252) | |
| momentum = returns.rolling(20).mean().iloc[-1] | |
| if momentum > 0 and vol < 0.25: | |
| return {"regime": "bull", "confidence": 0.7} | |
| elif momentum < 0: | |
| return {"regime": "bear", "confidence": 0.7} | |
| else: | |
| return {"regime": "sideways", "confidence": 0.6} | |
| # ============================================================ | |
| # FEATURE ENGINE | |
| # ============================================================ | |
| class AssetFeature: | |
| symbol: str | |
| expected_return: float | |
| confidence: float | |
| volatility: float | |
| returns: pd.Series | |
| regime: str | |
| class FeatureBuilder: | |
| def build(self, symbol, df, forecast, regime) -> AssetFeature: | |
| returns = np.log(df["Close"] / df["Close"].shift(1)).dropna() | |
| vol = returns.std() * np.sqrt(252) | |
| return AssetFeature( | |
| symbol=symbol, | |
| expected_return=forecast["expected_return"] * forecast["confidence"], | |
| confidence=forecast["confidence"], | |
| volatility=vol, | |
| returns=returns, | |
| regime=regime["regime"] | |
| ) | |
| # ============================================================ | |
| # OPTIMIZATION ENGINE | |
| # ============================================================ | |
| class Optimizer: | |
| def optimize(self, features: List[AssetFeature]) -> np.ndarray: | |
| returns = np.array([f.expected_return for f in features]) | |
| returns = np.clip(returns, -0.5, 0.5) | |
| returns_df = pd.concat( | |
| [f.returns for f in features], | |
| axis=1 | |
| ) | |
| returns_df.columns = [f.symbol for f in features] | |
| cov = returns_df.cov().values | |
| n = len(features) | |
| def objective(w): | |
| port_ret = w @ returns | |
| port_vol = np.sqrt(w @ cov @ w) | |
| return -(port_ret / (port_vol + 1e-8)) | |
| bounds = [(0.05, 0.5) for _ in range(n)] | |
| cons = [{"type": "eq", "fun": lambda w: np.sum(w) - 1}] | |
| w0 = np.ones(n) / n | |
| res = minimize(objective, w0, bounds=bounds, constraints=cons) | |
| return res.x if res.success else w0 | |
| # ============================================================ | |
| # RISK ANALYTICS | |
| # ============================================================ | |
| class RiskEngine: | |
| def analyze(self, weights, features): | |
| returns = np.array([f.expected_return for f in features]) | |
| returns_df = pd.concat([f.returns for f in features], axis=1) | |
| cov = returns_df.cov().values | |
| port_ret = weights @ returns | |
| port_vol = np.sqrt(weights @ cov @ weights) | |
| sharpe = (port_ret - 0.04) / port_vol if port_vol > 0 else 0 | |
| return { | |
| "expected_return": port_ret, | |
| "volatility": port_vol, | |
| "sharpe": sharpe | |
| } | |
| # ============================================================ | |
| # MAIN ORCHESTRATOR | |
| # ============================================================ | |
| class PortfolioApp: | |
| def __init__(self, symbols): | |
| self.symbols = symbols | |
| self.data_loader = MarketDataLoader() | |
| self.forecaster = SimpleAIForecaster() | |
| self.regime_detector = RegimeDetector() | |
| self.feature_builder = FeatureBuilder() | |
| self.optimizer = Optimizer() | |
| self.risk_engine = RiskEngine() | |
| def run(self): | |
| market_data = self.data_loader.fetch(self.symbols) | |
| features = [] | |
| for s, df in market_data.items(): | |
| forecast = self.forecaster.forecast(df["Close"]) | |
| returns = np.log(df["Close"] / df["Close"].shift(1)).dropna() | |
| regime = self.regime_detector.detect(returns) | |
| feature = self.feature_builder.build(s, df, forecast, regime) | |
| features.append(feature) | |
| weights = self.optimizer.optimize(features) | |
| risk = self.risk_engine.analyze(weights, features) | |
| print("\n📊 PORTFÖY SONUCU\n") | |
| for i, f in enumerate(features): | |
| print(f"{f.symbol:5s} | Weight: {weights[i]:.2%} | Regime: {f.regime}") | |
| print("\n--- RISK METRICS ---") | |
| print(f"Expected Return : {risk['expected_return']:.2%}") | |
| print(f"Volatility : {risk['volatility']:.2%}") | |
| print(f"Sharpe Ratio : {risk['sharpe']:.2f}") | |
| # ============================================================ | |
| # RUN | |
| # ============================================================ | |
| if __name__ == "__main__": | |
| symbols = ["XOM", "GOOGL", "WMT", "JNJ"] | |
| app = PortfolioApp(symbols) | |
| app.run() |