Untitled

 avatar
unknown
plain_text
3 months ago
3.2 kB
4
Indexable
import pandas as pd
import numpy as np

# Load historical price data
def load_price_data(file_path):
    return pd.read_excel(file_path, index_col=0, parse_dates=True)

# Initialize portfolio
def initialize_portfolio(tickers, aum, start_date, prices):
    initial_prices = prices.loc[start_date, tickers]
    quantities = aum / len(tickers) / initial_prices
    return pd.DataFrame({"Quantity": quantities, "Notional": quantities * initial_prices})

# Compute lookback metric
def compute_lookback_metric(prices, lookback_period, metric_type):
    if metric_type == "returns":
        return prices / prices.shift(lookback_period) - 1
    elif metric_type == "sma":
        sma = prices.rolling(lookback_period).mean()
        return (prices - sma) / sma
    return None

# Rank assets based on lookback metric
def rank_assets(metric_df):
    return metric_df.rank(axis=1, ascending=False, method='first')

# Compute rebalance amount
def compute_rebalance_amount(aum, rebalance_ratio):
    return aum * rebalance_ratio

# Perform rebalancing
def rebalance_portfolio(portfolio, prices, rebalance_amount, internal_rebalance_ratio, ranks):
    sorted_assets = ranks.iloc[-1].sort_values().index
    changes = rebalance_amount * np.array(internal_rebalance_ratio)
    
    for i, asset in enumerate(sorted_assets):
        portfolio.loc[asset, "Notional"] += changes[i]
        portfolio.loc[asset, "Quantity"] = portfolio.loc[asset, "Notional"] / prices.iloc[-1][asset]
    
    return portfolio

# Main execution function
def execute_strategy(file_path, tickers, aum, start_date, end_date, rebalance_period, rebalance_ratio, lookback_period, metric_type, internal_rebalance_ratio):
    prices = load_price_data(file_path)
    portfolio = initialize_portfolio(tickers, aum, start_date, prices)
    observation_dates = pd.date_range(start=start_date, end=end_date, freq=f'{rebalance_period}M')
    
    results = []
    for obs_date in observation_dates:
        if obs_date not in prices.index:
            continue
        lookback_metric = compute_lookback_metric(prices, lookback_period, metric_type).loc[obs_date]
        ranks = rank_assets(lookback_metric)
        aum_current = (portfolio["Quantity"] * prices.loc[obs_date]).sum()
        rebalance_amt = compute_rebalance_amount(aum_current, rebalance_ratio)
        portfolio = rebalance_portfolio(portfolio, prices.loc[[obs_date]], rebalance_amt, internal_rebalance_ratio, ranks)
        results.append([obs_date, aum_current] + list(portfolio["Quantity"]))
    
    return pd.DataFrame(results, columns=["Date", "AUM"] + list(tickers))

# Example usage
file_path = r"\\asiapac.nom\data\MUM\IWM\India_IWM_IPAS\Reet\Momentum Strategy\Codes\Historic Prices.xlsx"
tickers = ["EQ1", "EQ2", "EQ3", "FI1", "FI2", "FI3", "ALT1", "ALT2", "ALT3", "ALT4"]
aum = 100_000_000
start_date = "2025-01-01"
end_date = "2026-12-31"
rebalance_period = 1
rebalance_ratio = 0.1
lookback_period = 3
metric_type = "returns"
internal_rebalance_ratio = [0.7, 0.2, 0.1, 0, 0, 0, 0, -0.1, -0.2, -0.7]

final_results = execute_strategy(file_path, tickers, aum, start_date, end_date, rebalance_period, rebalance_ratio, lookback_period, metric_type, internal_rebalance_ratio)
print(final_results)
Editor is loading...
Leave a Comment