Untitled

 avatar
unknown
plain_text
8 days ago
2.7 kB
3
Indexable
def compute_daily_signals_and_ranks(prices_df, tickers, lookback_periods, correlation_lookback, negative_threshold=0.5):
    """
    Computes the aggregated momentum signals (using the correlation-adjusted, threshold approach)
    for each ticker on each unique date in the prices DataFrame, and then ranks the tickers per date.
    
    Parameters:
      prices_df: DataFrame with a "Date" column and asset price columns.
      tickers: List of tickers for which to compute signals (e.g. risk_on_list).
      lookback_periods: List of lookback periods in months (e.g. [3,6,9]).
      correlation_lookback: Lookback period (in months) for computing correlation.
      negative_threshold: Fraction threshold for negative signals (e.g., 0.5 for 50%).
      
    Returns:
      A DataFrame with columns: Date, Ticker, Aggregated Score, Is Positive, Signals, and Rank.
    """
    signals_records = []
    
    # Ensure dates are datetime and sort the DataFrame
    prices_df['Date'] = pd.to_datetime(prices_df['Date'])
    prices_df.sort_values('Date', inplace=True)
    
    # Iterate over each unique date in the prices DataFrame
    unique_dates = prices_df['Date'].unique()
    for d in unique_dates:
        for ticker in tickers:
            # Compute aggregated momentum for each ticker on date d using our modified function
            agg_score, is_positive, signals = compute_aggregated_momentum(
                prices_df, d, ticker, lookback_periods, correlation_lookback, universe=tickers, negative_threshold=negative_threshold
            )
            if agg_score is not None:
                signals_records.append({
                    'Date': d,
                    'Ticker': ticker,
                    'Aggregated Score': agg_score,
                    'Is Positive': is_positive,
                    'Signals': signals
                })
                
    # Create DataFrame from the records
    signals_df = pd.DataFrame(signals_records)
    
    # For each date, rank the tickers by Aggregated Score (descending order, so Rank 1 is best)
    signals_df['Rank'] = signals_df.groupby('Date')['Aggregated Score'].rank(ascending=False, method='min')
    signals_df.sort_values(['Date', 'Rank'], inplace=True)
    
    return signals_df

# Example usage:
# Assume 'prices' is your DataFrame with daily prices and a "Date" column.
# Assume risk_on_list is already defined.
df_daily_signals = compute_daily_signals_and_ranks(prices, risk_on_list, lookback_periods=[3, 6, 9], correlation_lookback=12, negative_threshold=0.5)

# Print the resulting DataFrame to see the signals and ranks for each ticker on each date.
print(df_daily_signals)
Editor is loading...
Leave a Comment