import pandas as pd import numpy as np class FinancialTools: @staticmethod def calculate_returns(prices_series, in_percent=True): # <-- NEUER PARAMETER HIER! """Berechnet die täglichen Renditen.""" if prices_series.empty: return pd.Series(dtype='float64') if isinstance(prices_series, pd.DataFrame): if 'adj_close' in prices_series.columns: prices_series = prices_series['adj_close'] elif 'close' in prices_series.columns: prices_series = prices_series['close'] else: return pd.Series(dtype='float64') returns = prices_series.pct_change().dropna() if in_percent: return returns * 100 # Für die Anzeige in Prozent return returns # Für interne Berechnungen (Dezimalwerte) @staticmethod def calculate_cumulative_returns(prices_series): """Berechnet die kumulativen Renditen.""" if prices_series.empty: return pd.Series(dtype='float64') # HIER: Rufe calculate_returns mit in_percent=False auf, um Dezimalwerte zu bekommen daily_returns_raw = FinancialTools.calculate_returns(prices_series, in_percent=False) if daily_returns_raw.empty: return pd.Series(dtype='float64') return (1 + daily_returns_raw).cumprod() - 1 @staticmethod def calculate_moving_average(prices_series, window=20): """Berechnet den gleitenden Durchschnitt.""" if prices_series.empty: return pd.Series(dtype='float64') if isinstance(prices_series, pd.DataFrame): if 'adj_close' in prices_series.columns: prices_series = prices_series['adj_close'] elif 'close' in prices_series.columns: prices_series = prices_series['close'] else: return pd.Series(dtype='float64') return prices_series.rolling(window=window).mean() @staticmethod def calculate_volatility(prices_series, window=20): """Berechnet die rollierende Volatilität (Standardabweichung der Renditen).""" if prices_series.empty: return pd.Series(dtype='float64') # HIER: Rufe calculate_returns mit in_percent=False auf, um Dezimalwerte zu bekommen daily_returns_for_vol = FinancialTools.calculate_returns(prices_series, in_percent=False) if daily_returns_for_vol.empty: return pd.Series(dtype='float64') # Annualisiere die Volatilität return daily_returns_for_vol.rolling(window=window).std() * np.sqrt(252) @staticmethod def calculate_beta(stock_prices, market_prices, window=60): """ Berechnet das rollierende Beta eines Wertpapiers relativ zu einem Marktindex. stock_prices: Pandas Series der Aktie market_prices: Pandas Series des Marktindex """ if stock_prices.empty or market_prices.empty: return pd.Series(dtype='float64') # Sicherstellen, dass es Series sind, falls doch DataFrames übergeben werden if isinstance(stock_prices, pd.DataFrame): if 'adj_close' in stock_prices.columns: stock_prices = stock_prices['adj_close'] elif 'close' in stock_prices.columns: stock_prices = stock_prices['close'] else: return pd.Series(dtype='float64') if isinstance(market_prices, pd.DataFrame): if 'adj_close' in market_prices.columns: market_prices = market_prices['adj_close'] elif 'close' in market_prices.columns: market_prices = market_prices['close'] else: return pd.Series(dtype='float64') # HIER: Rufe calculate_returns mit in_percent=False auf, um Dezimalwerte zu bekommen returns_stock = FinancialTools.calculate_returns(stock_prices, in_percent=False) returns_market = FinancialTools.calculate_returns(market_prices, in_percent=False) # Kombiniere die Renditen und richte sie an den Daten aus combined_returns = pd.concat([returns_stock.rename('stock'), returns_market.rename('market')], axis=1).dropna() if combined_returns.empty: return pd.Series(dtype='float64') # Berechne die rollierende Kovarianz und Varianz rolling_covariance = combined_returns['stock'].rolling(window=window).cov(combined_returns['market']) rolling_variance = combined_returns['market'].rolling(window=window).var() # Berechne Beta beta = rolling_covariance / rolling_variance return beta.dropna() # Beispielnutzung (für Tests) - Muss an die neuen Funktionssignaturen angepasst werden if __name__ == "__main__": # Erzeuge fiktive Daten für Tests dates = pd.to_datetime(pd.date_range(start='2023-01-01', periods=100)) stock_prices_series = pd.Series(np.random.rand(100) * 100 + 50, index=dates) # direkt als Series market_prices_series = pd.Series(np.random.rand(100) * 10 + 200, index=dates) # direkt als Series print("Tägliche Renditen (in Prozent):") print(FinancialTools.calculate_returns(stock_prices_series, in_percent=True).head()) # Für Anzeige print("\nKumulative Renditen (Dezimal):") print(FinancialTools.calculate_cumulative_returns(stock_prices_series).head()) print("\nGleitender 20-Tage-Durchschnitt:") print(FinancialTools.calculate_moving_average(stock_prices_series, window=20).head()) print("\nRollierende 20-Tage-Volatilität (annualisiert, Dezimal):") print(FinancialTools.calculate_volatility(stock_prices_series, window=20).head()) print("\nRollierendes 60-Tage-Beta (Aktie vs. Markt, Dezimal):") print(FinancialTools.calculate_beta(stock_prices_series, market_prices_series, window=60).head())