α52
Alpha 52
Where AI meets Quant

Code Snippets

Performance Metrics Calculation

Python code for calculating comprehensive performance metrics including Sharpe ratio, Sortino ratio, Alpha, Beta, and capture ratios.

Python
# fund_performance_df has the cumulative performance of both Fund & Benchmark 
# Create a copy of the provided DataFrame
df = fund_performance_df.copy()

# Fetch Annual Rf rate from any API
rf_annual = 0.046477

trading_days = len(df) - 1

rf_daily = (1 + rf_annual) ** (1 / 252) - 1
rf_period_ret = (1 + rf_daily) ** trading_days - 1

# Calculate MDD from cumulative TWR series (percentage-based)
model_water_line = df.model.expanding().max()
model_drawdown = (1 + df.model) / (1 + model_water_line) - 1
model_mdd = min(model_drawdown)

spy_water_line = df.spy.expanding().max()
spy_drawdown = (1 + df.spy) / (1 + spy_water_line) - 1
spy_mdd = min(spy_drawdown)

# Cumulative period returns
model_return = df['model'].iloc[-1]
spy_return = df['spy'].iloc[-1]

# Calculate daily returns: r_t = (1 + TWR_t) / (1 + TWR_{t-1}) - 1
df['model_daily_ret'] = (1 + df['model']) / (1 + df['model'].shift(1)) - 1
df['spy_daily_ret'] = (1 + df['spy']) / (1 + df['spy'].shift(1)) - 1

# Drop the first row (NaN due to shift) to get daily returns for the period
df = df.iloc[1:].reset_index(drop=True)

# Standard deviation of daily returns (scaled by sqrt(trading_days))
model_std_dev = np.std(df['model_daily_ret'], ddof=1) * np.sqrt(trading_days)
spy_std_dev = np.std(df['spy_daily_ret'], ddof=1) * np.sqrt(trading_days)

# Sharpe Ratio: (cumulative_return - rf_period_ret) / std_dev
model_sharpe = (model_return - rf_period_ret) / model_std_dev
spy_sharpe = (spy_return - rf_period_ret) / spy_std_dev

# Sortino Ratio: (cumulative_return - rf_period_ret) / downside_dev
def downside_deviation(returns, threshold=0):
    downside_returns = returns[returns < threshold]
    if len(downside_returns) == 0:
        return 0
    return np.std(downside_returns, ddof=1) * np.sqrt(trading_days)

model_downside_dev = downside_deviation(df['model_daily_ret'])
spy_downside_dev = downside_deviation(df['spy_daily_ret'])
model_sortino = (model_return - rf_period_ret) / model_downside_dev if model_downside_dev != 0 else np.inf
spy_sortino = (spy_return - rf_period_ret) / spy_downside_dev if spy_downside_dev != 0 else np.inf

# Beta: Cov(Fund, Benchmark) / Var(Benchmark)
cov_matrix = np.cov(df['model_daily_ret'], df['spy_daily_ret'], ddof=1)
beta = cov_matrix[0, 1] / cov_matrix[1, 1]

# Alpha: Fund Period Return - [Rf + Beta * (Benchmark Period Return - Rf)] (since-inception)
model_alpha = model_return - (rf_period_ret + beta * (spy_return - rf_period_ret))

# Tracking Error: Std of active daily returns (since-inception)
active_daily_return = df['model_daily_ret'] - df['spy_daily_ret']
model_track_error = np.std(active_daily_return, ddof=1) * np.sqrt(trading_days)

# Information Ratio: (model_return - spy_return) / track_error (since-inception)
model_info_ratio = (model_return - spy_return) / model_track_error if model_track_error != 0 else np.inf

# Up/Down Capture Ratios (using daily returns, since-inception)
up_days = df['spy_daily_ret'] > 0
down_days = df['spy_daily_ret'] < 0

# Cumulative returns for up/down periods (since-inception)
model_up_return = np.prod(1 + df['model_daily_ret'][up_days]) - 1 if up_days.sum() > 0 else 0
spy_up_return = np.prod(1 + df['spy_daily_ret'][up_days]) - 1 if up_days.sum() > 0 else 0
model_down_return = np.prod(1 + df['model_daily_ret'][down_days]) - 1 if down_days.sum() > 0 else 0
spy_down_return = np.prod(1 + df['spy_daily_ret'][down_days]) - 1 if down_days.sum() > 0 else 0

model_up_capture = (model_up_return / spy_up_return) if spy_up_return != 0 else np.inf
model_down_capture = (model_down_return / spy_down_return) if spy_down_return != 0 else np.inf

# Define metrics to be shown as percentages (multiplied by 100)
to_percentage = ['model_return', 'spy_return', 'model_mdd', 'spy_mdd', 'model_up_capture', 'model_down_capture', 'model_std_dev', 'spy_std_dev', 'model_alpha', 'model_track_error']

# Create list of dictionaries for JSON
metrics = [
    'model_duration',
    'model_return', 'spy_return', 'model_std_dev', 'spy_std_dev',
    'model_mdd', 'spy_mdd', 'model_sharpe', 'spy_sharpe',
    'model_sortino', 'spy_sortino', 'model_alpha', 'model_beta',
    'model_track_error', 'model_info_ratio', 'model_up_capture', 'model_down_capture'
]
values = [
    date_diff_str,
    model_return, spy_return, model_std_dev, spy_std_dev,
    model_mdd, spy_mdd, model_sharpe, spy_sharpe,
    model_sortino, spy_sortino, model_alpha, beta,
    model_track_error, model_info_ratio, model_up_capture, model_down_capture
]
values = [v if m == 'model_duration' else round(v * 100, 2) if m in to_percentage else round(v, 2) for m, v in zip(metrics, values)]  # Apply *100 for to_percentage, round to 2 decimals, except model_duration

# Build list of dictionaries
metrics_data = [{'metric': m, 'value': v} for m, v in zip(metrics, values)]

# Create DataFrame
model_metrices_df = pd.DataFrame(metrics_data)

Tutorials

Time Series Forecasting

This tutorial is an introduction to time series forecasting using TensorFlow. It builds a few different styles of models including Convolutional and Recurrent Neural Networks (CNNs and RNNs).

Open Tutorial open_in_new

Imbalanced Data Handling

It demonstrates how to deal with a highly imbalanced dataset in which the number of examples in one class greatly outnumbers the examples in another.

Open Tutorial open_in_new

Researches

Using Reinforcement Learning in the Algorithmic Trading Problem

Open Research Paper open_in_new

An Application of Deep Reinforcement Learning to Algorithmic Trading

Open Research Paper open_in_new
Home Stock Hot Lists Investments Insights
Support expand_more