class DataFetcher:
    def __init__(self, tickers, start_date='1990-01-01', end_date=None, auto_adjust=False):
        """
        Initializes the DataFetcher with tickers and date range.
        
        Parameters:
        - tickers (list or str): Stock ticker symbols.
        - start_date (str): Start date in 'YYYY-MM-DD' format.
        - end_date (str): End date in 'YYYY-MM-DD' format. Defaults to today if not provided.
        - auto_adjust (bool): Whether to adjust all OHLC prices. Defaults to False.
        """
        self.tickers = tickers if isinstance(tickers, list) else [tickers]
        self.start_date = start_date
        self.end_date = end_date if end_date else datetime.now().strftime('%Y-%m-%d')
        self.auto_adjust = auto_adjust
        self.data = None

    def fetch_data(self):
        """
        Fetches historical data for the specified tickers.
        """
        self.data = yf.download(
            self.tickers, 
            start=self.start_date, 
            end=self.end_date, 
            group_by='ticker',
            auto_adjust=self.auto_adjust,
            threads=True
        )
        # Handle single ticker case
        if len(self.tickers) == 1:
            self.data = {self.tickers[0]: self.data}
        else:
            self.data = {ticker: self.data[ticker] for ticker in self.tickers}
        return self.data
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import os
from scipy.stats import skew, kurtosis

class MonthlySeasonalityAnalyzer:
    def __init__(self, data, budget=4000, odds_ratio=2, output_dir='seasonality_data'):
        """
        Initializes the MonthlySeasonalityAnalyzer with necessary parameters.
        """
        self.data = data
        self.budget = budget
        self.odds_ratio = odds_ratio
        self.output_dir = output_dir
        if not os.path.exists(self.output_dir):
            os.makedirs(self.output_dir)

    @staticmethod
    def calculate_kelly_ratio(returns):
        """
        Calculates the Kelly ratio and fraction.
        """
        win_prob = np.mean(returns > 0)
        loss_prob = 1 - win_prob
        win_return = np.mean(returns[returns > 0]) if np.any(returns > 0) else 0
        loss_return = abs(np.mean(returns[returns < 0])) if np.any(returns < 0) else 0
        if loss_return == 0:
            kelly_ratio = 0
        else:
            kelly_ratio = (win_prob - (loss_prob / (win_return / loss_return))) if (win_return / loss_return) != 0 else 0
        kelly_fraction = kelly_ratio / 2  # Using half Kelly for safety
        return kelly_ratio, kelly_fraction

    @staticmethod
    def get_cell_colors(summary_table):
        """
        Generates cell colors for the summary table based on value ranges.
        """
        def color_scale(val, cmap, vmin, vmax):
            norm = plt.Normalize(vmin, vmax)
            return sns.color_palette(cmap, as_cmap=True)(norm(val))

        cell_colors = []
        for col in summary_table.columns:
            if col in ['Avg Returns (%)', 'Pos %', 'Avg Kelly Ratio', 'Avg Kelly Fraction', 'Position Size ($)']:
                cmap = "RdYlGn"
            elif col == 'StDev (%)':
                cmap = "YlOrRd"
            else:  # Skewness and Kurtosis
                cmap = "PuOr"
            vmin = summary_table[col].min()
            vmax = summary_table[col].max()
            colors = [color_scale(x, cmap, vmin, vmax) for x in summary_table[col]]
            cell_colors.append(colors)
        # Transpose to match table cell structure
        return list(map(list, zip(*cell_colors)))

    def analyze_monthly_seasonality(self, ticker):
        """
        Analyzes monthly seasonality for a given ticker.
        """
        df = self.data[ticker]['Adj Close'].resample('M').ffill()
        monthly_returns = df.pct_change().dropna() * 100  # Percentage

        # Organize into pivot table
        monthly_returns = monthly_returns.to_frame(name='Adj Close')
        monthly_returns['Year'] = monthly_returns.index.year
        monthly_returns['Month'] = monthly_returns.index.month
        monthly_returns['Month'] = monthly_returns['Month'].apply(lambda x: pd.Timestamp(2023, x, 1).strftime('%b'))
        pivot_table = monthly_returns.pivot_table(index='Year', columns='Month', values='Adj Close', aggfunc='mean')
        pivot_table = pivot_table.fillna(0)

        # Ensure correct month order
        months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
                  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
        pivot_table = pivot_table.reindex(columns=months)

        # Calculate metrics
        avg_returns = pivot_table.mean()
        std_dev = pivot_table.std()
        pos_perc = (pivot_table > 0).mean() * 100
        skewness = pivot_table.apply(lambda x: skew(x.dropna()), axis=0)
        kurt = pivot_table.apply(lambda x: kurtosis(x.dropna()), axis=0)

        # Kelly ratio and fraction
        kelly_ratios = pivot_table.apply(lambda x: self.calculate_kelly_ratio(x.dropna()), axis=0)
        avg_kelly_ratio = kelly_ratios.apply(lambda x: x[0])
        avg_kelly_fraction = kelly_ratios.apply(lambda x: x[1])

        # Position size based on Kelly fraction
        position_sizes = avg_kelly_fraction * self.budget

        # Summary table
        summary_table = pd.DataFrame({
            'Avg Returns (%)': avg_returns,
            'StDev (%)': std_dev,
            'Pos %': pos_perc,
            'Skewness': skewness,
            'Kurtosis': kurt,
            'Avg Kelly Ratio': avg_kelly_ratio,
            'Avg Kelly Fraction': avg_kelly_fraction,
            'Position Size ($)': position_sizes
        })

        return pivot_table, summary_table

    def visualize_monthly_seasonality(self, ticker):
        """
        Visualizes monthly seasonality with a heatmap and summary table.
        """
        pivot_table, summary_table = self.analyze_monthly_seasonality(ticker)

        fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(24, 8))
        
        # Heatmap
        sns.heatmap(
            pivot_table, 
            annot=True, 
            fmt=".2f", 
            cmap="coolwarm", 
            vmin=-5, 
            vmax=5, 
            center=0, 
            linewidths=.5, 
            cbar_kws={"shrink": .75}, 
            ax=ax1
        )
        ax1.set_title(f'Monthly Returns Heatmap for {ticker}', fontsize=16)
        ax1.set_xlabel('Month', fontsize=12)
        ax1.set_ylabel('Year', fontsize=12)
        ax1.tick_params(axis='both', which='major', labelsize=10)

        # Summary table
        ax2.axis('tight')
        ax2.axis('off')
        
        cell_colors = self.get_cell_colors(summary_table)
        
        table = ax2.table(
            cellText=summary_table.values.round(2), 
            colLabels=summary_table.columns, 
            rowLabels=summary_table.index, 
            cellLoc='center', 
            loc='center',
            cellColours=cell_colors
        )
        
        table.auto_set_font_size(False)
        table.set_fontsize(8)
        table.scale(1.2, 1.5)
        
        ax2.set_title(f'Summary Table for {ticker}', fontsize=16)

        plt.tight_layout()
        plt.show()

    def export_monthly_seasonality_data(self, ticker):
        """
        Exports monthly seasonality data to a CSV file.
        """
        _, summary_table = self.analyze_monthly_seasonality(ticker)
        output_path = os.path.join(self.output_dir, f'{ticker}_monthly_seasonality.csv')
        summary_table.to_csv(output_path)
        print(f'Saved {ticker} monthly seasonality data to {output_path}')
        

# Define the list of tickers for potential portfolio composition
tickers = {
    "broad_market": [
        "UPRO",  # UltraPro S&P500: 3x leveraged ETF of the S&P 500 Index
        "TQQQ"   # ProShares UltraPro QQQ: 3x leveraged ETF of the NASDAQ-100 Index
    ],
    "volatility": [
        "VIX",   # CBOE Volatility Index
        "UVXY"   # ProShares Ultra VIX Short-Term Futures ETF: 1.5x leveraged VIX futures
    ],
    "sectors": {
        "Technology": [
            "XLK",  # Technology Select Sector SPDR Fund
            "SOXL", # Direxion Daily Semiconductor Bull 3X Shares
            "SOXS"  # Direxion Daily Semiconductor Bear 3X Shares
        ],
        "Healthcare": [
            "XLV",  # Health Care Select Sector SPDR Fund
            "CURE", # Direxion Daily Healthcare Bull 2X Shares
            "SICK"  # Direxion Daily Healthcare Bear 2X Shares
        ],
        "Financials": [
            "XLF",  # Financial Select Sector SPDR Fund
            "FAS",  # Direxion Daily Financial Bull 3X Shares
            "FAZ"   # Direxion Daily Financial Bear 3X Shares
        ],
        "Consumer Discretionary": [
            "XLY",  # Consumer Discretionary Select Sector SPDR Fund
            "ERX",  # Direxion Daily Energy Bull 2X Shares
            "SCC"   # ProShares UltraShort Consumer Services
        ],
        "Energy": [
            "XLE",  # Energy Select Sector SPDR Fund
            "ERX",  # Direxion Daily Energy Bull 2X Shares
            "ERY"   # Direxion Daily Energy Bear 3X Shares
        ],
        "Industrials": [
            "XLI",  # Industrial Select Sector SPDR Fund
            "DUSL", # Direxion Daily Industrials Bull 3X Shares
            "SIJ"   # ProShares UltraShort Industrials
        ],
        "Communication Services": [
            "XLC",  # Communication Services Select Sector SPDR Fund
            "FNGU", # MicroSectors FANG+ Index 3X Leveraged ETN
            "FNGD"  # MicroSectors FANG+ Index -3X Inverse Leveraged ETN
        ],
        "Utilities": [
            "XLU",  # Utilities Select Sector SPDR Fund
            "UPW",  # ProShares Ultra Utilities
            "SDP"   # ProShares UltraShort Utilities
        ],
        "Materials": [
            "XLB",  # Materials Select Sector SPDR Fund
            "UYM",  # ProShares Ultra Basic Materials
            "SMN"   # ProShares UltraShort Basic Materials
        ]
    }
}

import numpy as np
import pandas as pd
import os

class DynamicKellyFraction:
    def __init__(self, ticker, initial_cash, margin_requirements, weekly_data_dir, monthly_data_dir):
        self.ticker = ticker
        self.cash = initial_cash  # Fixed initial cash
        self.current_cash = initial_cash  # Cash that updates over time
        self.margin_requirements = margin_requirements
        self.weekly_data_dir = weekly_data_dir
        self.monthly_data_dir = monthly_data_dir
        self.leveraged_etfs = ['TQQQ', 'UPRO', 'SOXL', 'FAS', 'LABU']  # Leveraged ETFs list
        
        # Initial Fed funds rate in basis points (e.g., 200 = 2%)
        self.fed_funds_rate = 200  # Starting point, can be updated dynamically
        
        # Kelly fractions mapping based on Fed stance
        self.base_kelly_fraction = 0.4  # Base Kelly fraction when Fed is neutral
        self.kelly_fraction_adjustment = {
            'dovish': +0.2,   # Increase Kelly fraction when Fed is dovish
            'hawkish': -0.2,  # Decrease Kelly fraction when Fed is hawkish
            'neutral': 0.0    # No change when Fed is neutral
        }
        
        # Historical cash balance for tracking performance
        self.cash_history = []

    def load_data(self):
        """
        Load weekly and monthly data from specified directories.
        """
        weekly_data = {}
        for file in sorted(os.listdir(self.weekly_data_dir)):
            if file.endswith(".csv"):
                week_num = int(file.split('_')[1].split('.')[0])  # Updated to use '_' as separator
                weekly_data[week_num] = pd.read_csv(os.path.join(self.weekly_data_dir, file))
            
        monthly_data = {}
        for file in sorted(os.listdir(self.monthly_data_dir)):
            if file.endswith(".csv"):
                month_num = int(file.split('_')[1].split('.')[0])  # Updated to use '_' as separator
                monthly_data[month_num] = pd.read_csv(os.path.join(self.monthly_data_dir, file))
            
        return weekly_data, monthly_data

    def update_fed_stance(self, rate_change_basis_points):
        """
        Update the Fed funds rate and adjust the Fed stance accordingly.
        """
        # Update the Fed funds rate
        self.fed_funds_rate += rate_change_basis_points
        
        # Determine the new Fed stance based on rate change
        if rate_change_basis_points < 0:
            self.fed_stance = 'dovish'
        elif rate_change_basis_points > 0:
            self.fed_stance = 'hawkish'
        else:
            self.fed_stance = 'neutral'
        
        print(f"Fed updated rates by {rate_change_basis_points} basis points. New Fed stance: {self.fed_stance}")
    
    def adjust_kelly_fraction(self, weekly_return, monthly_return):
        """
        Adjust the Kelly fraction based on returns and Fed stance.
        """
        # Base Kelly fraction
        kelly_fraction = self.base_kelly_fraction
        
        # Adjust based on market conditions
        if weekly_return > 0 and monthly_return > 0:
            # Bullish market
            market_outlook = 'bullish'
        elif weekly_return < 0 and monthly_return < 0:
            # Bearish market
            market_outlook = 'bearish'
            kelly_fraction *= -1  # Take short positions
        else:
            # Neutral market
            market_outlook = 'neutral'
        
        # Adjust for leveraged ETFs
        if self.ticker in self.leveraged_etfs:
            kelly_fraction *= 0.6  # Reduce Kelly fraction for leveraged ETFs

        # Adjust Kelly fraction based on Fed stance
        kelly_adjustment = self.kelly_fraction_adjustment.get(self.fed_stance, 0)
        kelly_fraction += kelly_adjustment

        # Ensure Kelly fraction is within bounds [-1, 1]
        kelly_fraction = max(min(kelly_fraction, 1), -1)
        
        # Debug statement
        print(f"Week analysis: Weekly return = {weekly_return:.4f}, Monthly return = {monthly_return:.4f}")
        print(f"Market outlook: {market_outlook}, Kelly fraction before Fed adjustment: {kelly_fraction:.4f}")
        
        return kelly_fraction

    def calculate_position_size(self, kelly_fraction):
        """
        Calculate position size based on the Kelly fraction and available cash.
        """
        initial_margin = self.margin_requirements['initial']
        leverage_factor = 1 / initial_margin
        max_position_size = self.current_cash * leverage_factor
        position_size = max_position_size * kelly_fraction
        
        # Ensure position size does not exceed max position size
        position_size = max(min(position_size, max_position_size), -max_position_size)
        
        return position_size

    def run_backtest(self):
        """
        Run the strategy over all weeks and months in the directories.
        """
        weekly_data, monthly_data = self.load_data()
        
        results = []
        
        total_weeks = len(weekly_data)
        for week in range(1, total_weeks + 1):
            # Determine corresponding month
            month_num = (week - 1) // 4 + 1
            monthly_returns = monthly_data.get(month_num, pd.DataFrame({'return': [0]}))['return']
            weekly_returns = weekly_data.get(week, pd.DataFrame({'return': [0]}))['return']

            monthly_return = monthly_returns.mean()
            weekly_return = weekly_returns.mean()

            # Adjust Kelly fraction
            kelly_fraction = self.adjust_kelly_fraction(weekly_return, monthly_return)
            
            # Calculate position size
            position_size = self.calculate_position_size(kelly_fraction)
            
            # Simulate trade
            trade_return = weekly_return * position_size
            self.current_cash += trade_return  # Update cash with trade result
            self.cash_history.append(self.current_cash)
            
            # Store the result
            results.append({
                'week': week,
                'position_size': position_size,
                'kelly_fraction': kelly_fraction,
                'weekly_return': weekly_return,
                'monthly_return': monthly_return,
                'trade_return': trade_return,
                'cash_balance': self.current_cash
            })
            
            # Debug statement
            print(f"Week {week}: Position size = {position_size:.2f}, Trade return = {trade_return:.2f}, Cash balance = {self.current_cash:.2f}")
        
        return pd.DataFrame(results)

# Synthetic data generation remains the same
def generate_realistic_data(num_periods, positive_trend=True):
    if positive_trend:
        return np.random.normal(0.005, 0.02, num_periods)
    else:
        return np.random.normal(-0.005, 0.03, num_periods)

def generate_synthetic_data_for_asset(weekly_data_dir, monthly_data_dir):
    os.makedirs(weekly_data_dir, exist_ok=True)
    os.makedirs(monthly_data_dir, exist_ok=True)
    
    for week in range(1, 53):
        if week < 27:
            weekly_returns = generate_realistic_data(100, positive_trend=True)
        else:
            weekly_returns = generate_realistic_data(100, positive_trend=False)
        weekly_df = pd.DataFrame({'return': weekly_returns})
        weekly_df.to_csv(os.path.join(weekly_data_dir, f'week_{week}.csv'), index=False)
    
    for month in range(1, 13):
        if month < 7:
            monthly_returns = generate_realistic_data(100, positive_trend=True)
        else:
            monthly_returns = generate_realistic_data(100, positive_trend=False)
        monthly_df = pd.DataFrame({'return': monthly_returns})
        monthly_df.to_csv(os.path.join(monthly_data_dir, f'month_{month}.csv'), index=False)

# Paths to save the synthetic data (change to valid paths on your system)
weekly_data_dir = './weekly_data'
monthly_data_dir = './monthly_data'

# Generate the data
generate_synthetic_data_for_asset(weekly_data_dir, monthly_data_dir)

# Instantiate the class
dynamic_kelly = DynamicKellyFraction(
    ticker='TSLA', 
    initial_cash=4000, 
    margin_requirements={'initial': 0.6, 'maintenance': 0.5}, 
    weekly_data_dir=weekly_data_dir, 
    monthly_data_dir=monthly_data_dir
)

# Simulate a Fed rate cut of 50 basis points
dynamic_kelly.update_fed_stance(rate_change_basis_points=-50)

# Run backtest and get results
backtest_results = dynamic_kelly.run_backtest()

# Display the first few rows
print("\nBacktest Results:")
print(backtest_results.head())


import logging
from datetime import datetime

# Configure logging to display INFO level messages
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')



# Define triple witching weeks (typically the 11th, 24th, 37th, and 50th weeks)
triple_witching_weeks = [11, 24, 37, 50]

# ------------------------- Data Fetching -------------------------
# Initialize DataFetcher with auto_adjust=False to include 'Adj Close'
data_fetcher = DataFetcher(
    tickers=tickers,  # Use the list of tickers directly
    start_date="2010-01-01",
    end_date="2024-01-01",
    auto_adjust=False
)
data = data_fetcher.fetch_data()

# ------------------ Weekly Seasonality Analysis ------------------
# Get the current week number of the year (1-52)
current_week = datetime.now().isocalendar()[1]

# Print the current week in bold
print(f"\033[1mCurrent Week: {current_week}\033[0m")

# Example usage of the MonthlySeasonalityAnalyzer and WeeklySeasonalityAnalyzer classes
if __name__ == "__main__":
    # Sample data fetching (replace with actual data fetching logic)
    data_fetcher = DataFetcher(tickers=tickers, start_date='2010-01-01')  # Use the list of tickers directly
    data = data_fetcher.fetch_data()

    # Create an instance of MonthlySeasonalityAnalyzer
    monthly_analyzer = MonthlySeasonalityAnalyzer(data=data)

    # Create an instance of WeeklySeasonalityAnalyzer
    weekly_analyzer = WeeklySeasonalityAnalyzer(
        data=data,
        triple_witching_weeks=[11, 24, 37, 50],
        odds_ratio=2,
        output_dir='seasonality_data',
        budget=4000
    )

    # Analyze and visualize monthly and weekly seasonality for each ticker in the list
    for ticker in tickers:
        try:
            logging.info(f"Analyzing Monthly Seasonality for {ticker}")
            monthly_analyzer.visualize_monthly_seasonality(ticker)

            logging.info(f"Analyzing Weekly Seasonality for {ticker}")
            weekly_analyzer.visualize_weekly_seasonality(ticker)
            weekly_analyzer.export_weekly_seasonality_data(ticker)
        except ValueError as ve:
            logging.error(f"ValueError for {ticker}: {ve}")
        except Exception as e:
            logging.error(f"Error analyzing {ticker}: {e}")
Explain why this is better:

import numpy as np
import pandas as pd
import os

class DynamicKellyFraction:
    def init(self, ticker, initial_cash, margin_requirements, weekly_data_dir, monthly_data_dir):
        self.ticker = ticker
        self.cash = initial_cash  # Fixed initial cash
        self.current_cash = initial_cash  # Cash that updates over time
        self.margin_requirements = margin_requirements
        self.weekly_data_dir = weekly_data_dir
        self.monthly_data_dir = monthly_data_dir
        self.leveraged_etfs = ['TQQQ', 'UPRO', 'SOXL', 'FAS', 'LABU']  # Leveraged ETFs list
        
        # Initial Fed funds rate in basis points (e.g., 200 = 2%)
        self.fed_funds_rate = 200  # Starting point, can be updated dynamically
        
        # Kelly fractions mapping based on Fed stance
        self.base_kelly_fraction = 0.4  # Base Kelly fraction when Fed is neutral
        self.kelly_fraction_adjustment = {
            'dovish': +0.2,   # Increase Kelly fraction when Fed is dovish
            'hawkish': -0.2,  # Decrease Kelly fraction when Fed is hawkish
            'neutral': 0.0    # No change when Fed is neutral
        }
        
        # Historical cash balance for tracking performance
        self.cash_history = []

    def load_data(self):
        """
        Load weekly and monthly data from specified directories.
        """
        weekly_data = {}
        for file in sorted(os.listdir(self.weekly_data_dir)):
            if file.endswith(".csv"):
                week_num = int(file.split('')[1].split('.')[0]) 
                weekly_data[week_num] = pd.read_csv(os.path.join(self.weekly_data_dir, file))
            
        monthly_data = {}
        for file in sorted(os.listdir(self.monthly_data_dir)):
            if file.endswith(".csv"):
                month_num = int(file.split('')[1].split('.')[0])
                monthly_data[month_num] = pd.read_csv(os.path.join(self.monthly_data_dir, file))
            
        return weekly_data, monthly_data

    def update_fed_stance(self, rate_change_basis_points):
        """
        Update the Fed funds rate and adjust the Fed stance accordingly.
        """
        # Update the Fed funds rate
        self.fed_funds_rate += rate_change_basis_points
        
        # Determine the new Fed stance based on rate change
        if rate_change_basis_points < 0:
            self.fed_stance = 'dovish'
        elif rate_change_basis_points > 0:
            self.fed_stance = 'hawkish'
        else:
            self.fed_stance = 'neutral'
        
        print(f"Fed updated rates by {rate_change_basis_points} basis points. New Fed stance: {self.fed_stance}")
    
    def adjust_kelly_fraction(self, weekly_return, monthly_return):
        """
        Adjust the Kelly fraction based on returns and Fed stance.
        """
        # Base Kelly fraction
        kelly_fraction = self.base_kelly_fraction
        
        # Adjust based on market conditions
        if weekly_return > 0 and monthly_return > 0:
            # Bullish market
            market_outlook = 'bullish'
        elif weekly_return < 0 and monthly_return < 0:
            # Bearish market
            market_outlook = 'bearish'
            kelly_fraction *= -1  # Take short positions
        else:
            # Neutral market
            market_outlook = 'neutral'
        
        # Adjust for leveraged ETFs
        if self.ticker in self.leveraged_etfs:
            kelly_fraction *= 0.6  # Reduce Kelly fraction for leveraged ETFs

        # Adjust Kelly fraction based on Fed stance
        kelly_adjustment = self.kelly_fraction_adjustment.get(self.fed_stance, 0)
        kelly_fraction += kelly_adjustment

        # Ensure Kelly fraction is within bounds [-1, 1]
        kelly_fraction = max(min(kelly_fraction, 1), -1)
        
        # Debug statement
        print(f"Week analysis: Weekly return = {weekly_return:.4f}, Monthly return = {monthly_return:.4f}")
        print(f"Market outlook: {market_outlook}, Kelly fraction before Fed adjustment: {kelly_fraction:.4f}")
        
        return kelly_fraction

    def calculate_position_size(self, kelly_fraction):
        """
        Calculate position size based on the Kelly fraction and available cash.
        """
        initial_margin = self.margin_requirements['initial']
        leverage_factor = 1 / initial_margin
        max_position_size = self.current_cash * leverage_factor
        position_size = max_position_size * kelly_fraction
        
        # Ensure position size does not exceed max position size
        position_size = max(min(position_size, max_position_size), -max_position_size)
        
        return position_size

    def run_backtest(self):
        """
        Run the strategy over all weeks and months in the directories.
        """
        weekly_data, monthly_data = self.load_data()
        
        results = []
        
        total_weeks = len(weekly_data)
        for week in range(1, total_weeks + 1):
            # Determine corresponding month
            month_num = (week - 1) // 4 + 1
            monthly_returns = monthly_data.get(month_num, pd.DataFrame({'return': [0]}))['return']
            weekly_returns = weekly_data.get(week, pd.DataFrame({'return': [0]}))['return']

            monthly_return = monthly_returns.mean()
            weekly_return = weekly_returns.mean()

            # Adjust Kelly fraction
            kelly_fraction = self.adjust_kelly_fraction(weekly_return, monthly_return)
            
            # Calculate position size
            position_size = self.calculate_position_size(kelly_fraction)
            
            # Simulate trade
            trade_return = weekly_return * position_size
            self.current_cash += trade_return  # Update cash with trade result
            self.cash_history.append(self.current_cash)
            
            # Store the result
            results.append({
                'week': week,
                'position_size': position_size,
                'kelly_fraction': kelly_fraction,
                'weekly_return': weekly_return,
                'monthly_return': monthly_return,
                'trade_return': trade_return,
                'cash_balance': self.current_cash
            })
            
            # Debug statement
            print(f"Week {week}: Position size = {position_size:.2f}, Trade return = {trade_return:.2f}, Cash balance = {self.current_cash:.2f}")
        
        return pd.DataFrame(results)

# Synthetic data generation remains the same
def generate_realistic_data(num_periods, positive_trend=True):
    if positive_trend:
        return np.random.normal(0.005, 0.02, num_periods)
    else:
        return np.random.normal(-0.005, 0.03, num_periods)

def generate_synthetic_data_for_asset(weekly_data_dir, monthly_data_dir):
    os.makedirs(weekly_data_dir, exist_ok=True)
    os.makedirs(monthly_data_dir, exist_ok=True)
    
    for week in range(1, 53):
        if week < 27:
            weekly_returns = generate_realistic_data(100, positive_trend=True)
        else:
            weekly_returns = generate_realistic_data(100, positive_trend=False)
        weekly_df = pd.DataFrame({'return': weekly_returns})
        weekly_df.to_csv(os.path.join(weekly_data_dir, f'week_{week}.csv'), index=False)
    
    for month in range(1, 13):
        if month < 7:
            monthly_returns = generate_realistic_data(100, positive_trend=True)
        else:
            monthly_returns = generate_realistic_data(100, positive_trend=False)
        monthly_df = pd.DataFrame({'return': monthly_returns})
        monthly_df.to_csv(os.path.join(monthly_data_dir, f'month_{month}.csv'), index=False)

# Paths to save the synthetic data (change to valid paths on your system)
weekly_data_dir = './weekly_data'
monthly_data_dir = './monthly_data'

# Generate the data
generate_synthetic_data_for_asset(weekly_data_dir, monthly_data_dir)

# Instantiate the class
dynamic_kelly = DynamicKellyFraction(
    ticker='TSLA', 
    initial_cash=4000, 
    margin_requirements={'initial': 0.6, 'maintenance': 0.5}, 
    weekly_data_dir=weekly_data_dir, 
    monthly_data_dir=monthly_data_dir
)

# Simulate a Fed rate cut of 50 basis points
dynamic_kelly.update_fed_stance(rate_change_basis_points=-50)

# Run backtest and get results
backtest_results = dynamic_kelly.run_backtest()

# Display the first few rows
print("\nBacktest Results:")
print(backtest_results.head())

I need to rewrite this code to use a dynamic